package org.ow2.chameleon.fuchsia.raspberry.pi.importer.test;

import junit.framework.Assert;
import org.apache.felix.ipojo.*;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.ow2.chameleon.fuchsia.core.declaration.ImportDeclaration;
import org.ow2.chameleon.fuchsia.core.declaration.ImportDeclarationBuilder;
import org.ow2.chameleon.fuchsia.core.exceptions.BinderException;
import org.ow2.chameleon.fuchsia.raspberry.pi.importer.GpIOImporter;

import java.util.Dictionary;
import java.util.HashMap;
import java.util.Map;

import static org.fest.reflect.core.Reflection.constructor;
import static org.fest.reflect.core.Reflection.field;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.*;

public class GpIOImporterTest {

    @Mock
    BundleContext context;

    @Mock
    GpIOImporter importer;

    @Mock
    ImportDeclaration declaration;

    @Mock
    ServiceReference importerServiceReference;

    @Mock
    Factory lightFactory;

    @Mock
    HandlerManager hm;

    @Before
    public void before() throws MissingHandlerException, UnacceptableConfiguration, ConfigurationException {

        MockitoAnnotations.initMocks(this);

        when(importerServiceReference.getProperty(org.osgi.framework.Constants.SERVICE_ID)).thenReturn(1l);

        declaration=spy(getValidDeclaration());
        declaration.bind(importerServiceReference);

        importer=spy(constructor().withParameterTypes(BundleContext.class).in(GpIOImporter.class).newInstance(context));

        when(lightFactory.createComponentInstance(any(Dictionary.class))).thenReturn(hm);

        field("lightFactory").ofType(Factory.class).in(importer).set(lightFactory);

        importer.validate();
        importer.registration(importerServiceReference);

    }

    @Test
    public void testInvalidDeclaration() throws BinderException {
        ImportDeclaration declaration=spy(getInvalidDeclaration());
        try{
            importer.registration(importerServiceReference);
            importer.useDeclaration(declaration);
            Assert.fail("A BinderException should have been thrown at this point");
        }catch(BinderException be){
            //An exception is normal here
        }
        verify(declaration,times(0)).handle(importerServiceReference);
    }

    @Test
    public void testValidDeclaration() throws BinderException {
        ImportDeclaration declaration=getValidDeclaration();
        declaration.bind(importerServiceReference);
        try{
            importer.registration(importerServiceReference);
            importer.useDeclaration(declaration);
        }catch(BinderException be){
            Assert.fail("A BinderException should have been thrown at this point");
        }
    }

    @Test
    public void testImporterUseDeclaration() throws BinderException, MissingHandlerException, UnacceptableConfiguration, ConfigurationException {
        importer.useDeclaration(declaration);
        Map<String, InstanceManager> gpioPin=field("gpioPin").ofType(Map.class).in(importer).get();
        verify(lightFactory,times(1)).createComponentInstance(any(Dictionary.class));
        verify(declaration,times(1)).handle(importerServiceReference);
        Assert.assertEquals(1,gpioPin.size());
    }

    @Test
    public void testImporterUseDeclarationNotTraceCaseException() throws MissingHandlerException, UnacceptableConfiguration, ConfigurationException {
        ImportDeclaration declaration=spy(getInvalidDeclaration());
        try{
            importer.useDeclaration(declaration);
        }catch(Exception e){
            //Swallow exception
        }
        Map<String, InstanceManager> gpioPin=field("gpioPin").ofType(Map.class).in(importer).get();
        verify(lightFactory,times(0)).createComponentInstance(any(Dictionary.class));
        verify(declaration,times(0)).handle(importerServiceReference);
        Assert.assertEquals(0,gpioPin.size());
    }

    @Test
    public void testImporterDenyDeclaration() throws BinderException, MissingHandlerException, UnacceptableConfiguration, ConfigurationException {
        importer.useDeclaration(declaration);
        Map<String, InstanceManager> gpioPin=field("gpioPin").ofType(Map.class).in(importer).get();
        Assert.assertEquals(1,gpioPin.size());
        importer.denyDeclaration(declaration);
        verify(declaration,times(1)).unhandle(importerServiceReference);
        Assert.assertEquals(0,gpioPin.size());
    }

    public ImportDeclaration getInvalidDeclaration(){
        Map<String,Object> meta=new HashMap<String,Object>();
        meta.put("id","id");
        ImportDeclaration declaration=ImportDeclarationBuilder.fromMetadata(meta).build();
        declaration.bind(importerServiceReference);
        return declaration;
    }

    public ImportDeclaration getValidDeclaration(){
        Map<String,Object> meta=new HashMap<String,Object>();
        meta.put("id","id");
        meta.put("importer.gpio.pin","1");
        meta.put("importer.gpio.name","lamp");
        ImportDeclaration declaration=ImportDeclarationBuilder.fromMetadata(meta).build();
        declaration.bind(importerServiceReference);
        return declaration;
    }

}

@@ -4065,32 +4065,894 @@
 size());%0A    %7D%0A%0A
+    @Test%0A    public void testGracefulServiceStop() throws MissingHandlerException, UnacceptableConfiguration, ConfigurationException %7B%0A        ImportDeclaration declaration=spy(getValidDeclaration());%0A        try%7B%0A            importer.useDeclaration(declaration);%0A        %7Dcatch(Exception e)%7B%0A            //Swallow exception%0A        %7D%0A%0A        Map%3CString, InstanceManager%3E gpioPin=field(%22gpioPin%22).ofType(Map.class).in(importer).get();%0A        verify(lightFactory,times(1)).createComponentInstance(any(Dictionary.class));%0A        verify(declaration,times(1)).handle(importerServiceReference);%0A        Assert.assertEquals(1,gpioPin.size());%0A        importer.invalidate();%0A        Assert.assertEquals(0,importer.getImportDeclarations().size());%0A    %7D%0A%0A    @Test%0A    public void importerNameCannotBeNull()%7B%0A        Assert.assertNotNull(importer.getName());%0A    %7D%0A%0A
     @Test%0A    pu

Add GPIO importer test