package org.ow2.chameleon.fuchsia.discovery.upnp;

/*
 * #%L
 * OW2 Chameleon - Fuchsia Discovery UPnP
 * %%
 * Copyright (C) 2009 - 2014 OW2 Chameleon
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */

import org.apache.felix.ipojo.annotations.*;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.service.upnp.UPnPDevice;
import org.ow2.chameleon.fuchsia.core.component.AbstractDiscoveryComponent;
import org.ow2.chameleon.fuchsia.core.component.DiscoveryService;
import org.ow2.chameleon.fuchsia.core.declaration.Constants;
import org.ow2.chameleon.fuchsia.core.declaration.ImportDeclaration;
import org.ow2.chameleon.fuchsia.core.declaration.ImportDeclarationBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

/**
 * Discovery UPnP  Detects the presence of a UPnP device (in a basedriver interface level) and publishes it as a importation declaration that can be seen by Fuchsia.
 *
 * @author jeremy.savonet@gmail.com
 * @author jander nascimento (botelho at imag.fr)
 */
@Component
@Provides(specifications = {DiscoveryService.class})
public class UPnPDiscovery extends AbstractDiscoveryComponent {

    private static final Logger LOG = LoggerFactory.getLogger(UPnPDiscovery.class);

    private final Map<String, ImportDeclaration> importDeclarations = new HashMap<String, ImportDeclaration>();

    @ServiceProperty(name = "instance.name")
    private String name;

    public UPnPDiscovery(BundleContext bundleContext) {
        super(bundleContext);
        LOG.debug("UPnP discovery: loading..");
    }

    @Validate
    public void start() {
        LOG.debug("UPnP discovery: up and running.");
    }

    @Invalidate
    public void stop() {
        super.stop();

        importDeclarations.clear();

        LOG.debug("UPnP discovery: stopped.");
    }

    public String getName() {
        return name;
    }

    @Bind(id = "upnp-device", specification = UPnPDevice.class, aggregate = true)
    public Object addingService(ServiceReference reference) {


        String deviceID = (String) reference.getProperty(UPnPDevice.FRIENDLY_NAME);
        String deviceType = (String) reference.getProperty(UPnPDevice.TYPE);
        String udn = (String) reference.getProperty(UPnPDevice.ID);

        createImportationDeclaration(deviceID, deviceType, udn, reference);

        return getBundleContext().getService(reference);
    }

    @Unbind(id = "upnp-device", specification = UPnPDevice.class, aggregate = true)
    public void removedService(ServiceReference reference) {

        String deviceID = (String) reference.getProperty(Constants.DEVICE_ID);

        ImportDeclaration importDeclaration = importDeclarations.get(deviceID);

        unregisterImportDeclaration(importDeclaration);

    }

    public Set<ImportDeclaration> getImportDeclarations() {
        return Collections.unmodifiableSet(new HashSet<ImportDeclaration>(importDeclarations.values()));
    }

    /**
     * Create an import declaration and delegates its registration for an upper class.
     */
    public synchronized void createImportationDeclaration(String deviceId, String deviceType, String deviceSubType, ServiceReference reference) {

        Map<String, Object> metadata = new HashMap<String, Object>();
        metadata.put(Constants.DEVICE_ID, deviceId);
        metadata.put(Constants.DEVICE_TYPE, deviceType);
        metadata.put(Constants.DEVICE_TYPE_SUB, deviceSubType);
        metadata.put("scope", "generic");

        ImportDeclaration declaration = ImportDeclarationBuilder.fromMetadata(metadata).build();

        importDeclarations.put(deviceId, declaration);

        registerImportDeclaration(declaration);
    }

}

@@ -2280,25 +2280,24 @@
 per.stop();%0A
-%0A
         impo
@@ -2316,25 +2316,24 @@
 ns.clear();%0A
-%0A
         LOG.
@@ -2525,22 +2525,20 @@
  public 
-Object
+void
  addingS
@@ -2574,18 +2574,16 @@
 ence) %7B%0A
-%0A%0A
         
@@ -2799,25 +2799,24 @@
 Device.ID);%0A
-%0A
         crea
@@ -2869,77 +2869,8 @@
  udn
-, reference);%0A%0A        return getBundleContext().getService(reference
 );%0A 
@@ -3012,33 +3012,32 @@
 ce reference) %7B%0A
-%0A
         String d
@@ -3095,25 +3095,24 @@
 DEVICE_ID);%0A
-%0A
         Impo
@@ -3179,17 +3179,16 @@
 iceID);%0A
-%0A
         
@@ -3231,25 +3231,24 @@
 claration);%0A
-%0A
     %7D%0A%0A    p
@@ -3635,41 +3635,12 @@
 Type
-, ServiceReference reference
 ) %7B%0A
-%0A
     
@@ -3875,24 +3875,24 @@
 ceSubType);%0A
+
         meta
@@ -3921,17 +3921,16 @@
 eric%22);%0A
-%0A
         

Fix issues in UPnPDiscovery