/**
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 2010 Bull S.A.S.
 * Contact: jonas-team@ow2.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 *
 * --------------------------------------------------------------------------
 * $Id$
 * --------------------------------------------------------------------------
 */


package org.ow2.jonas.cdi.weld.internal;

import java.util.Collection;
import java.util.HashSet;

import org.jboss.weld.bootstrap.spi.BeanDeploymentArchive;
import org.ow2.jonas.cdi.weld.internal.mock.MockBeanDeploymentArchive;
import org.testng.Assert;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;

/**
 * A {@code DefaultWeldServiceTestCase} is ...
 *
 * @author Guillaume Sauthier
 */
public class DefaultWeldServiceTestCase {

    private DefaultWeldService service;

    @BeforeTest
    private void setUp() throws Exception {
        service = new DefaultWeldService();
    }

    @Test
    public void testEachArchiveIsConnectedToOthers() throws Exception {
        // We provide a Collection of 3 archives
        Collection<BeanDeploymentArchive> set = new HashSet<BeanDeploymentArchive>();
        BeanDeploymentArchive a = new MockBeanDeploymentArchive("A");
        BeanDeploymentArchive b = new MockBeanDeploymentArchive("B");
        BeanDeploymentArchive c = new MockBeanDeploymentArchive("C");
        set.add(a);
        set.add(b);
        set.add(c);

        service.connectBeanDeploymentArchives(set, set);

        // We expect that each archive is connected to the 2 others

        // Ensure the collection has not changed
        Assert.assertEquals(set.size(), 3);

        // Check A -> (B + C)
        assertArchivesContained(a.getBeanDeploymentArchives(), b, c);

        // Check B -> (A + C)
        assertArchivesContained(b.getBeanDeploymentArchives(), a, c);

        // Check C -> (A + B)
        assertArchivesContained(c.getBeanDeploymentArchives(), a, b);

    }

    @Test
    public void testOneArchiveSetConnectionIsUntouched() throws Exception {
        // We provide a Collection of 3 archives
        Collection<BeanDeploymentArchive> set = new HashSet<BeanDeploymentArchive>();
        BeanDeploymentArchive a = new MockBeanDeploymentArchive("A");
        set.add(a);

        service.connectBeanDeploymentArchives(set, set);

        // Ensure the collection has not changed
        Assert.assertEquals(set.size(), 1);
        Assert.assertTrue(a.getBeanDeploymentArchives().isEmpty(), "No accessibles archives");

    }

    @Test
    public void testUniDirectionalLinkingFromSetOfArchivesToAnotherSet() throws Exception {

        // We provide a Collection of 3 archives
        Collection<BeanDeploymentArchive> childs = new HashSet<BeanDeploymentArchive>();
        BeanDeploymentArchive a = new MockBeanDeploymentArchive("A");
        BeanDeploymentArchive b = new MockBeanDeploymentArchive("B");
        childs.add(a);
        childs.add(b);

        // We provide a Collection of 3 archives
        Collection<BeanDeploymentArchive> parents = new HashSet<BeanDeploymentArchive>();
        BeanDeploymentArchive c = new MockBeanDeploymentArchive("C");
        BeanDeploymentArchive d = new MockBeanDeploymentArchive("D");
        parents.add(c);
        parents.add(d);

        service.connectBeanDeploymentArchives(childs, parents);

        // We expect that each archive is connected to the 2 others

        // Ensure the collections have not changed
        Assert.assertEquals(childs.size(), 2);
        Assert.assertEquals(parents.size(), 2);

        // Check A -> (C + D)
        assertArchivesContained(a.getBeanDeploymentArchives(), c, d);

        // Check B -> (C + D)
        assertArchivesContained(b.getBeanDeploymentArchives(), c, d);
    }

    private void assertArchivesContained(Collection<BeanDeploymentArchive> archives, BeanDeploymentArchive... expected) {

        // Ensure that childs size is the same than expected modules
        Assert.assertEquals(archives.size(), expected.length);

        // Ensure that each element is contained in the collection
        for (BeanDeploymentArchive element : expected) {
            Assert.assertTrue(archives.contains(element));
        }
    }
}
