/**
 * Copyright (c) 2014-2017 by the respective copyright holders.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 */
package org.eclipse.smarthome.core.thing.i18n;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import org.eclipse.smarthome.core.i18n.TranslationProvider;
import org.eclipse.smarthome.core.thing.type.BridgeType;
import org.eclipse.smarthome.core.thing.type.ChannelDefinition;
import org.eclipse.smarthome.core.thing.type.ChannelGroupDefinition;
import org.eclipse.smarthome.core.thing.type.ChannelGroupType;
import org.eclipse.smarthome.core.thing.type.ChannelType;
import org.eclipse.smarthome.core.thing.type.ThingType;
import org.eclipse.smarthome.core.thing.type.TypeResolver;
import org.osgi.framework.Bundle;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;

/**
 * This OSGi service could be used to localize a thing type using the I18N mechanism of the Eclipse SmartHome
 * framework.
 *
 * @author Markus Rathgeb - Move code from XML thing type provider to separate service
 * @author Laurent Garnier - fix localized label and description for channel group definition
 */
@Component(immediate = true, service = ThingTypeI18nLocalizationService.class)
public class ThingTypeI18nLocalizationService {

    private ThingTypeI18nUtil thingTypeI18nUtil;

    @Reference
    protected void setTranslationProvider(TranslationProvider i18nProvider) {
        this.thingTypeI18nUtil = new ThingTypeI18nUtil(i18nProvider);
    }

    protected void unsetTranslationProvider(TranslationProvider i18nProvider) {
        this.thingTypeI18nUtil = null;
    }

    public ThingType createLocalizedThingType(Bundle bundle, ThingType thingType, Locale locale) {
        final String label = this.thingTypeI18nUtil.getLabel(bundle, thingType.getUID(), thingType.getLabel(), locale);
        final String description = this.thingTypeI18nUtil.getDescription(bundle, thingType.getUID(),
                thingType.getDescription(), locale);

        final List<ChannelDefinition> localizedChannelDefinitions = new ArrayList<>(
                thingType.getChannelDefinitions().size());

        for (final ChannelDefinition channelDefinition : thingType.getChannelDefinitions()) {
            String channelLabel = this.thingTypeI18nUtil.getChannelLabel(bundle, thingType.getUID(), channelDefinition,
                    channelDefinition.getLabel(), locale);
            String channelDescription = this.thingTypeI18nUtil.getChannelDescription(bundle, thingType.getUID(),
                    channelDefinition, channelDefinition.getDescription(), locale);
            if (channelLabel == null || channelDescription == null) {
                ChannelType channelType = TypeResolver.resolve(channelDefinition.getChannelTypeUID(), locale);
                if (channelLabel == null) {
                    channelLabel = this.thingTypeI18nUtil.getChannelLabel(bundle, channelType.getUID(),
                            channelType.getLabel(), locale);
                }
                if (channelDescription == null) {
                    channelDescription = this.thingTypeI18nUtil.getChannelDescription(bundle, channelType.getUID(),
                            channelType.getDescription(), locale);
                }
            }
            localizedChannelDefinitions
                    .add(new ChannelDefinition(channelDefinition.getId(), channelDefinition.getChannelTypeUID(),
                            channelDefinition.getProperties(), channelLabel, channelDescription));
        }

        final List<ChannelGroupDefinition> localizedChannelGroupDefinitions = new ArrayList<>(
                thingType.getChannelGroupDefinitions().size());
        for (final ChannelGroupDefinition channelGroupDefinition : thingType.getChannelGroupDefinitions()) {
            String channelGroupLabel = this.thingTypeI18nUtil.getChannelGroupLabel(bundle, thingType.getUID(),
                    channelGroupDefinition, channelGroupDefinition.getLabel(), locale);
            String channelGroupDescription = this.thingTypeI18nUtil.getChannelGroupDescription(bundle,
                    thingType.getUID(), channelGroupDefinition, channelGroupDefinition.getDescription(), locale);
            if (channelGroupLabel == null || channelGroupDescription == null) {
                ChannelGroupType channelGroupType = TypeResolver.resolve(channelGroupDefinition.getTypeUID(), locale);
                if (channelGroupLabel == null) {
                    channelGroupLabel = this.thingTypeI18nUtil.getChannelGroupLabel(bundle, channelGroupType.getUID(),
                            channelGroupType.getLabel(), locale);
                }
                if (channelGroupDescription == null) {
                    channelGroupDescription = this.thingTypeI18nUtil.getChannelGroupDescription(bundle,
                            channelGroupType.getUID(), channelGroupType.getDescription(), locale);
                }
            }
            localizedChannelGroupDefinitions.add(new ChannelGroupDefinition(channelGroupDefinition.getId(),
                    channelGroupDefinition.getTypeUID(), channelGroupLabel, channelGroupDescription));
        }

        if (thingType instanceof BridgeType) {
            final BridgeType bridgeType = (BridgeType) thingType;
            return new BridgeType(bridgeType.getUID(), bridgeType.getSupportedBridgeTypeUIDs(), label, description,
                    thingType.isListed(), thingType.getRepresentationProperty(), localizedChannelDefinitions,
                    localizedChannelGroupDefinitions, thingType.getProperties(), bridgeType.getConfigDescriptionURI());
        } else {
            return new ThingType(thingType.getUID(), thingType.getSupportedBridgeTypeUIDs(), label, description,
                    thingType.isListed(), thingType.getRepresentationProperty(), localizedChannelDefinitions,
                    localizedChannelGroupDefinitions, thingType.getProperties(), thingType.getConfigDescriptionURI());
        }
    }

}

@@ -3023,32 +3023,79 @@
 UID(), locale);%0A
+                if (channelType != null) %7B%0A    
                 
@@ -3138,24 +3138,28 @@
             
+    
 channelLabel
@@ -3250,32 +3250,36 @@
                 
+    
 channelType.getL
@@ -3287,32 +3287,36 @@
 bel(), locale);%0A
+    
                 
@@ -3325,32 +3325,36 @@
                 
+    
 if (channelDescr
@@ -3363,32 +3363,36 @@
 tion == null) %7B%0A
+    
                 
@@ -3511,32 +3511,36 @@
                 
+   
+ 
 channelType.getD
@@ -3554,32 +3554,54 @@
 ion(), locale);%0A
+                    %7D%0A
                 
@@ -4754,32 +4754,84 @@
 UID(), locale);%0A
+                if (channelGroupType != null) %7B%0A    
                 
@@ -4855,32 +4855,36 @@
 abel == null) %7B%0A
+    
                 
@@ -4962,35 +4962,8 @@
 dle,
- channelGroupType.getUID(),
 %0A   
@@ -4978,32 +4978,63 @@
                 
+     channelGroupType.getUID(),
  channelGroupTyp
@@ -5064,34 +5064,42 @@
                 
-%7D%0A
+    %7D%0A    
                 
@@ -5149,32 +5149,36 @@
                 
+  
+  
 channelGroupDesc
@@ -5265,32 +5265,36 @@
                 
+    
 channelGroupType
@@ -5340,32 +5340,54 @@
 ion(), locale);%0A
+                    %7D%0A
                 

fix issue #4152 (#4171)