package org.ow2.chameleon.fuchsia.core.component.test;

import org.junit.After;
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.ServiceRegistration;
import org.ow2.chameleon.fuchsia.core.component.AbstractDiscoveryComponent;
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.Dictionary;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.*;

public class AbstractDiscoveryComponentTest {


    @Mock
    BundleContext bundleContext;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this); //initialize the object with mocks annotations
    }

    @After
    public void tearDown() {

    }

    @Test
    public void testInstantiation(){
        TestedClass testedClass = new TestedClass(bundleContext);
        testedClass.start();
    }

    @Test
    public void testRegisterImportDeclaration(){
        TestedClass testedClass = new TestedClass(bundleContext);
        testedClass.start();

        Map<String, Object> md = new HashMap<String, Object>();
        md.put("md", "value");
        ImportDeclaration id = ImportDeclarationBuilder.fromMetadata(md).build();

        testedClass.addIdec(id);
        Dictionary <String, Object> props = new Hashtable<String, Object>();
        String clazzes[] = new String[]{ImportDeclaration.class.getName()};
        verify(bundleContext).registerService(clazzes, id, props);

        assertThat(testedClass.getImportDeclarations()).containsExactly(id);
    }

    @Test(expected = IllegalStateException.class)
    public void testRegisterTwoTimesImportDeclaration(){
        TestedClass testedClass = new TestedClass(bundleContext);
        testedClass.start();

        Map<String, Object> md = new HashMap<String, Object>();
        md.put("md", "value");
        ImportDeclaration id = ImportDeclarationBuilder.fromMetadata(md).build();

        testedClass.addIdec(id);
        testedClass.addIdec(id);
    }

    @Test
    public void testUnregisterImportDeclaration(){
        TestedClass testedClass = new TestedClass(bundleContext);
        testedClass.start();

        Map<String, Object> md = new HashMap<String, Object>();
        md.put("md", "value");
        ImportDeclaration id = ImportDeclarationBuilder.fromMetadata(md).build();

        ServiceRegistration mockSR = mock(ServiceRegistration.class);
        Dictionary <String, Object> props = new Hashtable<String, Object>();
        String clazzes[] = new String[]{ImportDeclaration.class.getName()};
        when(bundleContext.registerService(clazzes, id, props)).thenReturn(mockSR);

        testedClass.addIdec(id);
        testedClass.removeIdec(id);

        assertThat(testedClass.getImportDeclarations()).isEmpty();
    }

    @Test(expected = IllegalStateException.class)
    public void testUnregisterTwoTimesImportDeclaration(){
        TestedClass testedClass = new TestedClass(bundleContext);
        testedClass.start();

        Map<String, Object> md = new HashMap<String, Object>();
        md.put("md", "value");
        ImportDeclaration id = ImportDeclarationBuilder.fromMetadata(md).build();

        ServiceRegistration mockSR = mock(ServiceRegistration.class);
        Dictionary <String, Object> props = new Hashtable<String, Object>();
        String clazzes[] = new String[]{ImportDeclaration.class.getName()};
        when(bundleContext.registerService(clazzes, id, props)).thenReturn(mockSR);

        testedClass.addIdec(id);
        testedClass.removeIdec(id);
        testedClass.removeIdec(id);
    }

    @Test
    public void testStop(){
        TestedClass testedClass = new TestedClass(bundleContext);
        testedClass.start();

        Map<String, Object> md = new HashMap<String, Object>();
        md.put("md", "value");
        ImportDeclaration id = ImportDeclarationBuilder.fromMetadata(md).build();

        ServiceRegistration mockSR = mock(ServiceRegistration.class);
        Dictionary <String, Object> props = new Hashtable<String, Object>();
        String clazzes[] = new String[]{ImportDeclaration.class.getName()};
        when(bundleContext.registerService(clazzes, id, props)).thenReturn(mockSR);

        testedClass.addIdec(id);
        testedClass.stop();

        assertThat(testedClass.getImportDeclarations()).isEmpty();
    }

    @Test
    public void testToString(){
        TestedClass testedClass = new TestedClass(bundleContext);
        testedClass.start();

        String string = testedClass.toString();
        assertThat(string).isEqualTo("name");
    }



    public class TestedClass extends AbstractDiscoveryComponent{

        protected TestedClass(BundleContext bundleContext) {
            super(bundleContext);
        }

        @Override
        public Logger getLogger() {
            return LoggerFactory.getLogger(this.getClass());
        }

        public String getName() {
            return "name";
        }

        @Override
        protected void start() {
            super.start();
        }

        @Override
        protected void stop() {
            super.stop();
        }

        public void addIdec(ImportDeclaration importDeclaration){
            registerImportDeclaration(importDeclaration);
        }

        public void removeIdec(ImportDeclaration importDeclaration){
            unregisterImportDeclaration(importDeclaration);
        }
    }
}

@@ -121,16 +121,45 @@
 t.Test;%0A
+import org.mockito.Matchers;%0A
 import o
@@ -175,16 +175,16 @@
 o.Mock;%0A
-
 import o
@@ -378,16 +378,79 @@
 ponent;%0A
+import org.ow2.chameleon.fuchsia.core.declaration.Declaration;%0A
 import o
@@ -1067,16 +1067,190 @@
 tations%0A
+        when(bundleContext.registerService(any(String%5B%5D.class), any(Declaration.class), any(Dictionary.class)))%0A                .thenReturn(mock(ServiceRegistration.class));%0A
     %7D%0A%0A 
@@ -1815,161 +1815,8 @@
 d);%0A
-        Dictionary %3CString, Object%3E props = new Hashtable%3CString, Object%3E();%0A        String clazzes%5B%5D = new String%5B%5D%7BImportDeclaration.class.getName()%7D;%0A
     
@@ -1839,16 +1839,25 @@
 eContext
+,times(1)
 ).regist
@@ -1866,34 +1866,66 @@
 Service(
-clazzes, 
+any(String%5B%5D.class), eq(
 id
+)
 , 
-props
+any(Dictionary.class)
 );%0A%0A    
@@ -2866,245 +2866,8 @@
 ss);
-%0A        Dictionary %3CString, Object%3E props = new Hashtable%3CString, Object%3E();%0A        String clazzes%5B%5D = new String%5B%5D%7BImportDeclaration.class.getName()%7D;%0A        when(bundleContext.registerService(clazzes, id, props)).thenReturn(mockSR);
 %0A%0A  
@@ -3395,316 +3395,8 @@
 );%0A%0A
-        ServiceRegistration mockSR = mock(ServiceRegistration.class);%0A        Dictionary %3CString, Object%3E props = new Hashtable%3CString, Object%3E();%0A        String clazzes%5B%5D = new String%5B%5D%7BImportDeclaration.class.getName()%7D;%0A        when(bundleContext.registerService(clazzes, id, props)).thenReturn(mockSR);%0A%0A
     
@@ -3724,32 +3724,32 @@
 %22md%22, %22value%22);%0A
+
         ImportDe
@@ -3819,316 +3819,8 @@
 );%0A%0A
-        ServiceRegistration mockSR = mock(ServiceRegistration.class);%0A        Dictionary %3CString, Object%3E props = new Hashtable%3CString, Object%3E();%0A        String clazzes%5B%5D = new String%5B%5D%7BImportDeclaration.class.getName()%7D;%0A        when(bundleContext.registerService(clazzes, id, props)).thenReturn(mockSR);%0A%0A
     

Add test on AbstractDiscoveryComponent