/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */
package org.apache.felix.metatype;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;

import org.osgi.service.metatype.AttributeDefinition;
import org.xmlpull.v1.XmlPullParserException;

import junit.framework.TestCase;

/**
 * The <code>MetaDataReaderTest</code> class tests the
 * <code>MetaDataReader</code> class.
 *
 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
 */
public class MetaDataReaderTest extends TestCase
{
    private MetaDataReader reader;

    @Override
    protected void setUp() throws Exception
    {
        super.setUp();

        reader = new MetaDataReader();
    }

    @Override
    protected void tearDown() throws Exception
    {
        reader = null;

        super.tearDown();
    }

    public void testEmpty() throws IOException, XmlPullParserException
    {
        String empty = "<MetaData />";
        MetaData mti = read(empty);

        // Implicitly assume the lowest version...
        assertEquals(MetaDataReader.NAMESPACE_1_0, mti.getNamespace());
        assertNull(mti.getLocalePrefix());
        assertNull(mti.getObjectClassDefinitions());
    }

    public void testOptionalAttributesInMetaData() throws IOException, XmlPullParserException
    {
        String name = "myattribute";
        String value = "working";
        String localization = "test";
        String empty = "<MetaData " + name + "=\"" + value + "\" localization=\"" + localization + "\" />";
        MetaData mti = read(empty);

        assertEquals(localization, mti.getLocalePrefix());
        assertNull(mti.getObjectClassDefinitions());
        assertNotNull(mti.getOptionalAttributes());
        assertEquals(1, mti.getOptionalAttributes().size());
        assertEquals(value, mti.getOptionalAttributes().get(name));
    }

    public void testWithNamespace_1_0_0() throws IOException, XmlPullParserException
    {
        String empty = "<metatype:MetaData xmlns:metatype=\"" + MetaDataReader.NAMESPACE_1_0 + "\" " + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ></metatype:MetaData>";
        MetaData mti = read(empty);

        assertNotNull(mti);
        assertEquals(MetaDataReader.NAMESPACE_1_0, mti.getNamespace());
        assertNull(mti.getLocalePrefix());
        assertNull(mti.getObjectClassDefinitions());
    }

    public void testWithNamespace_1_1_0() throws IOException, XmlPullParserException
    {
        String empty = "<metatype:MetaData xmlns:metatype=\"" + MetaDataReader.NAMESPACE_1_1 + "\" " + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ></metatype:MetaData>";
        MetaData mti = read(empty);

        assertNotNull(mti);
        assertEquals(MetaDataReader.NAMESPACE_1_1, mti.getNamespace());
        assertNull(mti.getLocalePrefix());
        assertNull(mti.getObjectClassDefinitions());
    }

    public void testWithNamespace_1_2_0() throws IOException, XmlPullParserException
    {
        String empty = "<metatype:MetaData xmlns:metatype=\"" + MetaDataReader.NAMESPACE_1_2 + "\" " + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ></metatype:MetaData>";
        MetaData mti = read(empty);

        assertNotNull(mti);
        assertEquals(MetaDataReader.NAMESPACE_1_2, mti.getNamespace());
        assertNull(mti.getLocalePrefix());
        assertNull(mti.getObjectClassDefinitions());
    }

    public void testWithNamespace_1_3_0() throws IOException, XmlPullParserException
    {
        String empty = "<metatype:MetaData xmlns:metatype=\"" + MetaDataReader.NAMESPACE_1_3 + "\" " + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ></metatype:MetaData>";
        MetaData mti = read(empty);

        assertNotNull(mti);
        assertEquals(MetaDataReader.NAMESPACE_1_3, mti.getNamespace());
        assertNull(mti.getLocalePrefix());
        assertNull(mti.getObjectClassDefinitions());
    }

    public void testWithNamespace_1_4_0() throws IOException, XmlPullParserException
    {
        String empty = "<metatype:MetaData xmlns:metatype=\"" + MetaDataReader.NAMESPACE_1_4 + "\" " + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ></metatype:MetaData>";
        MetaData mti = read(empty);

        assertNotNull(mti);
        assertEquals(MetaDataReader.NAMESPACE_1_4, mti.getNamespace());
        assertNull(mti.getLocalePrefix());
        assertNull(mti.getObjectClassDefinitions());
    }

    public void testWithInvalidNamespaceUri()
    {
        String empty = "<metatype:MetaData xmlns:metatype=\"http://www.osgi.org/xmlns/datatype/v1.0.0\" " + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ></metatype:MetaData>";

        try
        {
            read(empty);
            fail("Parse failure expected for unsupported namespace URI");
        }
        catch (IOException e)
        {
            // expected due to unsupported namespace URI
        }
    }

    public void testWithInvalidNamespaceName()
    {
        String empty = "<datatype:MetaData xmlns:metatype=\"http://www.osgi.org/xmlns/metatype/v1.0.0\" " + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ></datatype:MetaData>";

        try
        {
            read(empty);
            fail("Parse failure expected for undefined namespace prefix");
        }
        catch (IOException e)
        {
            // expected due to undefined namespace prefix used
        }
    }

    public void testEmptyLocalization() throws IOException, XmlPullParserException
    {
        String testLoc = "OSGI-INF/folder/base";
        String empty = "<MetaData localization=\"" + testLoc + "\"/>";
        MetaData mti = read(empty);

        assertEquals(testLoc, mti.getLocalePrefix());
    }

    public void testSingleOCDOk() throws IOException, XmlPullParserException
    {
        String ocdName = "ocd0";
        String ocdId = "id.ocd0";
        String ocdDescription = "ocd0 description";

        String empty = "<MetaData><OCD id=\"" + ocdId + "\" name=\"" + ocdName + "\" description=\"" + ocdDescription + "\"><AD id=\"attr\" type=\"String\" required=\"false\" /></OCD></MetaData>";
        MetaData mti = read(empty);

        assertNull(mti.getLocalePrefix());
        assertNotNull(mti.getObjectClassDefinitions());
        assertEquals(1, mti.getObjectClassDefinitions().size());

        OCD ocd = (OCD) mti.getObjectClassDefinitions().values().iterator().next();
        assertEquals(ocdId, ocd.getID());
        assertEquals(ocdName, ocd.getName());
        assertEquals(ocdDescription, ocd.getDescription());

        assertNotNull(ocd.getAttributeDefinitions());
    }

    /**
     * FELIX-4665 - Default values can be empty.
     */
    public void testAttributeWithDefaultValueOk() throws IOException, XmlPullParserException
    {
        String xml;

        xml = "<MetaData><OCD id=\"ocd\" name=\"ocd\"><AD id=\"attr\" type=\"String\" required=\"false\" default=\"\" /></OCD></MetaData>";
        MetaData mti = read(xml);
        OCD ocd = (OCD) mti.getObjectClassDefinitions().get("ocd");
        AD ad = (AD) ocd.getAttributeDefinitions().get("attr");
        // Cardinality = 0, so *always* return a array with length 1...
        assertTrue(Arrays.deepEquals(new String[] { "" }, ad.getDefaultValue()));

        xml = "<MetaData><OCD id=\"ocd\" name=\"ocd\"><AD id=\"attr\" cardinality=\"1\" type=\"String\" required=\"false\" /></OCD></MetaData>";
        mti = read(xml);
        ocd = (OCD) mti.getObjectClassDefinitions().get("ocd");
        ad = (AD) ocd.getAttributeDefinitions().get("attr");
        // Cardinality = 1, return an array with *up to* 1 elements...
        assertNull(ad.getDefaultValue());

        xml = "<MetaData><OCD id=\"ocd\" name=\"ocd\"><AD id=\"attr\" cardinality=\"1\" type=\"String\" required=\"false\" default=\"\" /></OCD></MetaData>";
        mti = read(xml);
        ocd = (OCD) mti.getObjectClassDefinitions().get("ocd");
        ad = (AD) ocd.getAttributeDefinitions().get("attr");
        // Cardinality = 1, return an array with *up to* 1 elements...
        assertTrue(Arrays.deepEquals(new String[] { "" }, ad.getDefaultValue()));

        // The metatype spec defines that getDefaultValue should never have more entries than defined in its (non-zero) cardinality...
        xml = "<MetaData><OCD id=\"ocd\" name=\"ocd\"><AD id=\"attr\" cardinality=\"1\" type=\"String\" required=\"false\" default=\",\" /></OCD></MetaData>";
        mti = read(xml);
        ocd = (OCD) mti.getObjectClassDefinitions().get("ocd");
        ad = (AD) ocd.getAttributeDefinitions().get("attr");
        // Cardinality = 1, return an array with *up to* 1 elements...
        assertTrue(Arrays.deepEquals(new String[] { "" }, ad.getDefaultValue()));
    }

    /**
     * FELIX-4644 - Enforce that we can only have one Object in a Designate element.
     */
    public void testOCDWithoutADFail() throws IOException, XmlPullParserException
    {
        String ocdName = "ocd0";
        String ocdId = "id.ocd0";
        String ocdDescription = "ocd0 description";

        String xml = "<MetaData><OCD id=\"" + ocdId + "\" name=\"" + ocdName + "\" description=\"" + ocdDescription + "\" /></MetaData>";

        final MetaData md = read(xml);
        assertNull(md.getObjectClassDefinitions());
    }

    /**
     * FELIX-4644 - MetaType v1.3 allows OCDs without ADs.
     */
    public void testOCDWithoutADOk_v13() throws IOException, XmlPullParserException
    {
        String ocdName = "ocd0";
        String ocdId = "id.ocd0";
        String ocdDescription = "ocd0 description";

        String xml = "<metatype:MetaData xmlns:metatype=\"" + MetaDataReader.NAMESPACE_1_3 + "\" " + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ><OCD id=\"" + ocdId + "\" name=\""
            + ocdName + "\" description=\"" + ocdDescription + "\" /></metatype:MetaData>";

        MetaData mti = read(xml);

        assertNull(mti.getLocalePrefix());
        assertNotNull(mti.getObjectClassDefinitions());
        assertEquals(1, mti.getObjectClassDefinitions().size());

        OCD ocd = (OCD) mti.getObjectClassDefinitions().values().iterator().next();
        assertEquals(ocdId, ocd.getID());
        assertEquals(ocdName, ocd.getName());
        assertEquals(ocdDescription, ocd.getDescription());

        assertNull(ocd.getAttributeDefinitions());
    }

    /**
     * FELIX-4644 - Enforce that we can only have one Object in a Designate element.
     */
    public void testDesignateWithoutObjectFail() throws IOException, XmlPullParserException
    {
        String ocdName = "ocd0";
        String ocdId = "id.ocd0";
        String ocdDescription = "ocd0 description";
        String pid = "myPID";

        String xml = "<MetaData><OCD id=\"" + ocdId + "\" name=\"" + ocdName + "\" description=\"" + ocdDescription + "\"><AD id=\"attr\" type=\"String\" required=\"false\" /></OCD><Designate pid=\""
            + pid + "\" bundle=\"*\"></Designate></MetaData>";

        final MetaData md = read(xml);
        assertNull(md.getDesignates());
        assertEquals(1, md.getObjectClassDefinitions().size());
    }

    /**
     * FELIX-4644 - Enforce that we can only have one Object in a Designate element.
     */
    public void testDesignateWithObjectOk() throws IOException, XmlPullParserException
    {
        String ocdName = "ocd0";
        String ocdId = "id.ocd0";
        String ocdDescription = "ocd0 description";
        String pid = "myPID";

        String xml = "<MetaData><OCD id=\"" + ocdId + "\" name=\"" + ocdName + "\" description=\"" + ocdDescription + "\"><AD id=\"attr\" type=\"String\" required=\"false\" /></OCD><Designate pid=\""
            + pid + "\" bundle=\"*\"><Object ocdref=\"" + ocdId + "\"></Object></Designate></MetaData>";
        MetaData mti = read(xml);

        assertNull(mti.getLocalePrefix());
        assertNotNull(mti.getObjectClassDefinitions());
        assertEquals(1, mti.getObjectClassDefinitions().size());

        OCD ocd = (OCD) mti.getObjectClassDefinitions().values().iterator().next();
        assertEquals(ocdId, ocd.getID());
        assertEquals(ocdName, ocd.getName());
        assertEquals(ocdDescription, ocd.getDescription());

        assertNotNull(ocd.getAttributeDefinitions());

        List designates = ocd.getMetadata().getDesignates();
        assertEquals(1, designates.size());

        Designate designate = (Designate) designates.get(0);
        assertEquals(pid, designate.getPid());
        assertNotNull(designate.getObject());
    }

    /**
     * FELIX-4644 - Enforce that we can only have one Object in a Designate element.
     */
    public void testDesignateWithTwoObjectsFail() throws IOException, XmlPullParserException
    {
        String ocdName = "ocd0";
        String ocdId = "id.ocd0";
        String ocdDescription = "ocd0 description";
        String pid = "myPID";

        String xml = "<MetaData><OCD id=\"" + ocdId + "\" name=\"" + ocdName + "\" description=\"" + ocdDescription + "\"><AD id=\"attr\" type=\"String\" required=\"false\" /></OCD><Designate pid=\""
            + pid + "\" bundle=\"*\"><Object ocdref=\"" + ocdId + "\"></Object><Object ocdref=\"" + ocdId + "\"></Object></Designate></MetaData>";

        try
        {
            read(xml); // should fail!
            fail("IOException expected!");
        }
        catch (IOException e)
        {
            assertTrue(e.getMessage().contains("Unexpected element Object"));
        }
    }

    /**
     * FELIX-4799 - tests that we can have multiple designates for the same factory PID in one MetaData configuration.
     */
    public void testMultipleFactoryDesignatesWithSamePidOk() throws IOException, XmlPullParserException
    {
        String xml = "<MetaData><OCD id=\"ocd\" name=\"ocd\"><AD id=\"attr\" type=\"String\" required=\"false\" /></OCD>"
            + "<Designate factoryPid=\"factoryA\" pid=\"A\" bundle=\"*\"><Object ocdref=\"ocd\"><Attribute adref=\"attr\" value=\"foo\" /></Object></Designate>"
            + "<Designate factoryPid=\"factoryA\" pid=\"B\" bundle=\"*\"><Object ocdref=\"ocd\"><Attribute adref=\"attr\" value=\"bar\" /></Object></Designate>" + "</MetaData>";

        MetaData metadata = read(xml);
        assertNotNull(metadata);

        assertEquals(1, metadata.getObjectClassDefinitions().size());
        assertEquals(2, metadata.getDesignates().size());
    }

    /**
     * FELIX-4799 - tests that we can have multiple designates for the same factory PID in one MetaData configuration.
     */
    public void testMultipleFactoryDesignatesWithDifferentPidsOk() throws IOException, XmlPullParserException
    {
        String xml = "<MetaData><OCD id=\"ocd\" name=\"ocd\"><AD id=\"attr\" type=\"String\" required=\"false\" /></OCD>"
            + "<Designate factoryPid=\"factoryA\" pid=\"A\" bundle=\"*\"><Object ocdref=\"ocd\"><Attribute adref=\"attr\" value=\"foo\" /></Object></Designate>"
            + "<Designate factoryPid=\"factoryB\" pid=\"A\" bundle=\"*\"><Object ocdref=\"ocd\"><Attribute adref=\"attr\" value=\"bar\" /></Object></Designate>" + "</MetaData>";

        MetaData metadata = read(xml);
        assertNotNull(metadata);

        assertEquals(1, metadata.getObjectClassDefinitions().size());
        assertEquals(2, metadata.getDesignates().size());
    }

    public void testSingleOCDSingleRequiredAttr() throws IOException, XmlPullParserException
    {
        testSingleOCDSingleRequiredAttr("String", AttributeDefinition.STRING, MetaDataReader.NAMESPACE_1_0);
        testSingleOCDSingleRequiredAttr("String", AttributeDefinition.STRING, MetaDataReader.NAMESPACE_1_1);
        testSingleOCDSingleRequiredAttr("String", AttributeDefinition.STRING, MetaDataReader.NAMESPACE_1_2);
        testSingleOCDSingleRequiredAttr("String", AttributeDefinition.STRING, MetaDataReader.NAMESPACE_1_3);

        testSingleOCDSingleRequiredAttr("Char", AttributeDefinition.CHARACTER, MetaDataReader.NAMESPACE_1_0);
        testSingleOCDSingleRequiredAttr("Char", AttributeDefinition.CHARACTER, MetaDataReader.NAMESPACE_1_1);
        testSingleOCDSingleRequiredAttr("Char", AttributeDefinition.CHARACTER, MetaDataReader.NAMESPACE_1_2);
        testSingleOCDSingleRequiredAttr("Char", AttributeDefinition.CHARACTER, MetaDataReader.NAMESPACE_1_3);

        testSingleOCDSingleRequiredAttr("Character", AttributeDefinition.CHARACTER, MetaDataReader.NAMESPACE_1_0);
        testSingleOCDSingleRequiredAttr("Character", AttributeDefinition.CHARACTER, MetaDataReader.NAMESPACE_1_1);
        testSingleOCDSingleRequiredAttr("Character", AttributeDefinition.CHARACTER, MetaDataReader.NAMESPACE_1_2);
        testSingleOCDSingleRequiredAttr("Character", AttributeDefinition.CHARACTER, MetaDataReader.NAMESPACE_1_3);

    }

    private void testSingleOCDSingleRequiredAttr(String adType, int typeCode, String namespace) throws IOException
    {
        String ocdName = "ocd0";
        String ocdId = "id.ocd0";
        String ocdDescription = "ocd0 description";

        String adId = "id.ad0";
        String adName = "ad0";
        String adDescription = "ad0 description";
        int adCardinality = 789;
        String adDefault = "    a    ,   b    ,    c    ";

        String empty = "<metatype:MetaData xmlns:metatype=\"" + namespace + "\">" + "<OCD id=\"" + ocdId + "\" name=\"" + ocdName + "\" description=\"" + ocdDescription + "\">" + "<AD id=\"" + adId
            + "\" name=\"" + adName + "\" type=\"" + adType + "\" description=\"" + adDescription + "\" cardinality=\"" + adCardinality + "\" default=\"" + adDefault + "\">" + "</AD>" + "</OCD>"
            + "</metatype:MetaData>";
        MetaData mti = read(empty);

        assertNull(mti.getLocalePrefix());
        assertNotNull(mti.getObjectClassDefinitions());
        assertEquals(1, mti.getObjectClassDefinitions().size());

        OCD ocd = (OCD) mti.getObjectClassDefinitions().values().iterator().next();

        assertNotNull(ocd.getAttributeDefinitions());
        assertEquals(1, ocd.getAttributeDefinitions().size());

        AD ad = (AD) ocd.getAttributeDefinitions().values().iterator().next();
        assertEquals(adId, ad.getID());
        assertEquals(adName, ad.getName());
        assertEquals(adDescription, ad.getDescription());
        assertEquals(typeCode, ad.getType());
        assertEquals(adCardinality, ad.getCardinality());
        assertNotNull(ad.getDefaultValue());
        assertEquals(3, ad.getDefaultValue().length);

        String[] defaultValue = ad.getDefaultValue();
        assertEquals("a", defaultValue[0]);
        assertEquals("b", defaultValue[1]);
        assertEquals("c", defaultValue[2]);
    }

    private MetaData read(String data) throws IOException
    {
        InputStream input = new ByteArrayInputStream(data.getBytes("UTF-8"));
        return reader.parse(input);
    }
}
