/*
 * 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.cm.file;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.List;

import org.junit.Assert;
import org.junit.Test;

public class ConfigurationHandlerTest {

    private static final String SERVICE_PID = "service.pid";

    private static final String PAR_1 = "mongouri";
    private static final String VAL_1 = "127.0.0.1:27017";
    private static final String PAR_2 = "customBlobStore";
    private static final String VAL_2 = "true";

    private static final String CONFIG =
        "#mongodb URI\n" +
        PAR_1 + "=\"" + VAL_1 + "\"\n" +
        "\n" +
        "  # custom datastore\n" +
        PAR_2 + "=B\"" + VAL_2 + "\"\n";

    @Test
    public void testComments() throws IOException
    {
        @SuppressWarnings("unchecked")
        final Dictionary<String, Object> dict = ConfigurationHandler.read(new ByteArrayInputStream(CONFIG.getBytes("UTF-8")));
        Assert.assertEquals(2, dict.size());
        Assert.assertEquals(VAL_1, dict.get(PAR_1));
        Assert.assertEquals(VAL_2, dict.get(PAR_2).toString());
    }


    @Test
    public void test_writeArray() throws IOException {
        OutputStream out = new ByteArrayOutputStream();
        Dictionary< String, Object> properties = new Hashtable<>();
        properties.put(SERVICE_PID , new String [] {"foo", "bar"});
        ConfigurationHandler.write(out, properties);
        String entry = new String(((ByteArrayOutputStream)out).toByteArray(),"UTF-8");
        Assert.assertEquals("service.pid=[ \\\r\n  \"foo\", \\\r\n  \"bar\", \\\r\n  ]\r\n", entry);
    }

    @Test
    public void test_writeEmptyCollection() throws IOException {
        OutputStream out = new ByteArrayOutputStream();
        Dictionary< String, Object> properties = new Hashtable<>();
        properties.put(SERVICE_PID , new ArrayList<String>());
        ConfigurationHandler.write(out, properties);
        String entry = new String(((ByteArrayOutputStream)out).toByteArray(),"UTF-8");
        Assert.assertEquals("service.pid=( \\\r\n)\r\n", entry);
    }

    @Test
    public void test_writeCollection() throws IOException {
        OutputStream out = new ByteArrayOutputStream();
        Dictionary< String, Object> properties = new Hashtable<>();
        List<String> list = new ArrayList<>();
        list.add("foo");
        list.add("bar");

        properties.put(SERVICE_PID , list);
        ConfigurationHandler.write(out, properties);
        String entry = new String(((ByteArrayOutputStream)out).toByteArray(),"UTF-8");
        Assert.assertEquals("service.pid=( \\\r\n  \"foo\", \\\r\n  \"bar\", \\\r\n)\r\n", entry);
    }

    @Test
    public void test_writeSimpleString() throws IOException {
        OutputStream out = new ByteArrayOutputStream();
        Dictionary< String, String> properties = new Hashtable<>();
        properties.put(SERVICE_PID, "com.adobe.granite.foo.Bar");
        ConfigurationHandler.write(out, properties);
        String entry = new String(((ByteArrayOutputStream)out).toByteArray(),"UTF-8");
        Assert.assertEquals("service.pid=\"com.adobe.granite.foo.Bar\"\r\n", entry);
    }

    @Test
    public void test_writeInteger() throws IOException {
        OutputStream out = new ByteArrayOutputStream();
        Dictionary< String, Integer> properties = new Hashtable<>();
        properties.put(SERVICE_PID, 1000);
        ConfigurationHandler.write(out, properties);
        String entry = new String(((ByteArrayOutputStream)out).toByteArray(),"UTF-8");
        Assert.assertEquals("service.pid=I\"1000\"\r\n", entry);
    }

    @Test
    public void test_writeLong() throws IOException {
        OutputStream out = new ByteArrayOutputStream();
        Dictionary< String, Long> properties = new Hashtable<>();
        properties.put(SERVICE_PID, 1000L);
        ConfigurationHandler.write(out, properties);
        String entry = new String(((ByteArrayOutputStream)out).toByteArray(),"UTF-8");
        Assert.assertEquals("service.pid=L\"1000\"\r\n", entry);
    }

    @Test
    public void test_writeFloat() throws IOException {
        OutputStream out = new ByteArrayOutputStream();
        Dictionary< String, Float> properties = new Hashtable<>();
        properties.put(SERVICE_PID, 3.6f);
        ConfigurationHandler.write(out, properties);
        String entry = new String(((ByteArrayOutputStream)out).toByteArray(),"UTF-8");
        Assert.assertEquals("service.pid=F\"1080452710\"\r\n", entry);
    }

    @Test
    public void test_writeDouble() throws IOException {
        OutputStream out = new ByteArrayOutputStream();
        Dictionary< String, Double> properties = new Hashtable<>();
        properties.put(SERVICE_PID, 3.6d);
        ConfigurationHandler.write(out, properties);
        String entry = new String(((ByteArrayOutputStream)out).toByteArray(),"UTF-8");
        Assert.assertEquals("service.pid=D\"4615288898129284301\"\r\n", entry);
    }

    @Test
    public void test_writeByte() throws IOException {
        OutputStream out = new ByteArrayOutputStream();
        Dictionary< String, Byte> properties = new Hashtable<>();
        properties.put(SERVICE_PID, Byte.parseByte("10"));
        ConfigurationHandler.write(out, properties);
        String entry = new String(((ByteArrayOutputStream)out).toByteArray(),"UTF-8");
        Assert.assertEquals("service.pid=X\"10\"\r\n", entry);
    }

    @Test
    public void test_writeShort() throws IOException {
        OutputStream out = new ByteArrayOutputStream();
        Dictionary< String, Short> properties = new Hashtable<>();
        properties.put(SERVICE_PID, (short)10);
        ConfigurationHandler.write(out, properties);
        String entry = new String(((ByteArrayOutputStream)out).toByteArray(),"UTF-8");
        Assert.assertEquals("service.pid=S\"10\"\r\n", entry);
    }

    @Test
    public void test_writeChar() throws IOException {
        OutputStream out = new ByteArrayOutputStream();
        Dictionary< String, Character> properties = new Hashtable<>();
        properties.put(SERVICE_PID, 'c');
        ConfigurationHandler.write(out, properties);
        String entry = new String(((ByteArrayOutputStream)out).toByteArray(),"UTF-8");
        Assert.assertEquals("service.pid=C\"c\"\r\n", entry);
    }

    @Test
    public void test_writeBoolean() throws IOException {
        OutputStream out = new ByteArrayOutputStream();
        Dictionary< String, Boolean> properties = new Hashtable<>();
        properties.put(SERVICE_PID, true);
        ConfigurationHandler.write(out, properties);
        String entry = new String(((ByteArrayOutputStream)out).toByteArray(),"UTF-8");
        Assert.assertEquals("service.pid=B\"true\"\r\n", entry);
    }

    @Test
    public void test_writeSimpleStringWithError() throws IOException {
        OutputStream out = new ByteArrayOutputStream();
        Dictionary< String, String> properties = new Hashtable<>();
        properties.put("foo.bar", "com.adobe.granite.foo.Bar");
        ConfigurationHandler.write(out, properties);
        String entry = new String(((ByteArrayOutputStream)out).toByteArray(),"UTF-8");
        Assert.assertEquals("foo.bar=\"com.adobe.granite.foo.Bar\"\r\n", entry);
    }

    @Test
    public void test_readArray() throws IOException {
        String entry = "service.pid=[ \\\r\n  \"foo\", \\\r\n  \"bar\", \\\r\n  ]\r\n";
        InputStream stream = new ByteArrayInputStream(entry.getBytes(StandardCharsets.UTF_8));
        @SuppressWarnings("unchecked")
        Dictionary<String, Object> dictionary = ConfigurationHandler.read(stream);
        Assert.assertEquals(1, dictionary.size());
        Assert.assertArrayEquals(new String [] {"foo", "bar"}, (String [])dictionary.get(SERVICE_PID));
    }

    @Test
    public void test_readEmptyCollection() throws IOException {
        String entry = "service.pid=( \\\r\n)\r\n";
        InputStream stream = new ByteArrayInputStream(entry.getBytes(StandardCharsets.UTF_8));
        @SuppressWarnings("unchecked")
        Dictionary<String, Object> dictionary = ConfigurationHandler.read(stream);
        Assert.assertEquals(1, dictionary.size());
        Assert.assertEquals(new ArrayList<String>(), dictionary.get(SERVICE_PID));
    }

    @Test
    public void test_readCollection() throws IOException {
        String entry = "service.pid=( \\\r\n  \"foo\", \\\r\n  \"bar\", \\\r\n)\r\n";
        InputStream stream = new ByteArrayInputStream(entry.getBytes(StandardCharsets.UTF_8));
        @SuppressWarnings("unchecked")
        Dictionary<String, Object> dictionary = ConfigurationHandler.read(stream);
        Assert.assertEquals(1, dictionary.size());
        List<String> list = new ArrayList<>();
        list.add("foo");
        list.add("bar");
        Assert.assertEquals(list, dictionary.get(SERVICE_PID));
    }

    @Test
    public void test_readSimpleString() throws IOException {
        String entry = "service.pid=\"com.adobe.granite.foo.Bar\"\r\n";
        InputStream stream = new ByteArrayInputStream(entry.getBytes(StandardCharsets.UTF_8));
        @SuppressWarnings("unchecked")
        Dictionary<String, Object> dictionary = ConfigurationHandler.read(stream);
        Assert.assertEquals(1, dictionary.size());
        Assert.assertEquals( "com.adobe.granite.foo.Bar", dictionary.get(SERVICE_PID));
    }

    @Test
    public void test_readSimpleStrings() throws IOException {
        String entry = "service.pid=\"com.adobe.granite.foo.Bar\"\r\nfoo.bar=\"com.adobe.granite.foo.Baz\"\r\n";
        InputStream stream = new ByteArrayInputStream(entry.getBytes(StandardCharsets.UTF_8));
        @SuppressWarnings("unchecked")
        Dictionary<String, Object> dictionary = ConfigurationHandler.read(stream);
        Assert.assertEquals(2, dictionary.size());
        Assert.assertEquals( "com.adobe.granite.foo.Bar", dictionary.get(SERVICE_PID));
        Assert.assertNotNull(dictionary.get("foo.bar"));
    }

    @Test
    public void test_readInteger() throws IOException {
        String entry = "service.pid=I\"1000\"\r\n";
        InputStream stream = new ByteArrayInputStream(entry.getBytes(StandardCharsets.UTF_8));
        @SuppressWarnings("unchecked")
        Dictionary<String, Object> dictionary = ConfigurationHandler.read(stream);
        Assert.assertEquals(1, dictionary.size());
        Assert.assertEquals( 1000, dictionary.get(SERVICE_PID));
    }

    @Test
    public void test_readLong() throws IOException {
        String entry = "service.pid=L\"1000\"\r\n";
        InputStream stream = new ByteArrayInputStream(entry.getBytes(StandardCharsets.UTF_8));
        @SuppressWarnings("unchecked")
        Dictionary<String, Object> dictionary = ConfigurationHandler.read(stream);
        Assert.assertEquals(1, dictionary.size());
        Assert.assertEquals( 1000L, dictionary.get(SERVICE_PID));
    }

    @Test
    public void test_readFloat() throws IOException {
        String entry = "service.pid=F\"1080452710\"\r\n";
        InputStream stream = new ByteArrayInputStream(entry.getBytes(StandardCharsets.UTF_8));
        @SuppressWarnings("unchecked")
        Dictionary<String, Object> dictionary = ConfigurationHandler.read(stream);
        Assert.assertEquals(1, dictionary.size());
        Assert.assertEquals( 3.6f, dictionary.get(SERVICE_PID));
    }

    @Test
    public void test_readDouble() throws IOException {
        String entry = "service.pid=D\"4615288898129284301\"\r\n";
        InputStream stream = new ByteArrayInputStream(entry.getBytes(StandardCharsets.UTF_8));
        @SuppressWarnings("unchecked")
        Dictionary<String, Object> dictionary = ConfigurationHandler.read(stream);
        Assert.assertEquals(1, dictionary.size());
        Assert.assertEquals( 3.6d, dictionary.get(SERVICE_PID));
    }

    @Test
    public void test_readByte() throws IOException {
        String entry = "service.pid=X\"10\"\r\n";
        InputStream stream = new ByteArrayInputStream(entry.getBytes(StandardCharsets.UTF_8));
        @SuppressWarnings("unchecked")
        Dictionary<String, Object> dictionary = ConfigurationHandler.read(stream);
        Assert.assertEquals(1, dictionary.size());
        Assert.assertEquals((byte)10 , dictionary.get(SERVICE_PID));
    }

    @Test
    public void test_readShort() throws IOException {
        String entry = "service.pid=S\"10\"\r\n";
        InputStream stream = new ByteArrayInputStream(entry.getBytes(StandardCharsets.UTF_8));
        @SuppressWarnings("unchecked")
        Dictionary<String, Object> dictionary = ConfigurationHandler.read(stream);
        Assert.assertEquals(1, dictionary.size());
        Assert.assertEquals((short)10 , dictionary.get(SERVICE_PID));
    }

    @Test
    public void test_readChar() throws IOException {
        String entry = "service.pid=C\"c\"\r\n";
        InputStream stream = new ByteArrayInputStream(entry.getBytes(StandardCharsets.UTF_8));
        @SuppressWarnings("unchecked")
        Dictionary<String, Object> dictionary = ConfigurationHandler.read(stream);
        Assert.assertEquals(1, dictionary.size());
        Assert.assertEquals('c' , dictionary.get(SERVICE_PID));
    }

    @Test
    public void test_readBoolean() throws IOException {
        String entry = "service.pid=B\"true\"\r\n";
        InputStream stream = new ByteArrayInputStream(entry.getBytes(StandardCharsets.UTF_8));
        @SuppressWarnings("unchecked")
        Dictionary<String, Object> dictionary = ConfigurationHandler.read(stream);
        Assert.assertEquals(1, dictionary.size());
        Assert.assertEquals(true , dictionary.get(SERVICE_PID));
    }

    @Test
    public void test_backslash() throws IOException {
        final String VALUE = "val\\ue\\\\";
        final Dictionary<String, Object> dict = new Hashtable<>();
        dict.put("key", VALUE);
        try (final ByteArrayOutputStream out = new ByteArrayOutputStream()) {
            ConfigurationHandler.write(out, dict);

            try (final ByteArrayInputStream ins = new ByteArrayInputStream(out.toByteArray())) {
                @SuppressWarnings("unchecked")
                final Dictionary<String, Object> read = ConfigurationHandler.read(ins);

                Assert.assertNotNull(read.get("key"));
                Assert.assertEquals(VALUE, read.get("key"));
            }
        }
    }

    @Test
    public void test_readElementWithWhitespaceBeforeEQ() throws IOException {
        String entry = "service.pid  =\n\"com.adobe.granite.foo.Bar\"\r\n";
        InputStream stream = new ByteArrayInputStream(entry.getBytes(StandardCharsets.UTF_8));
        @SuppressWarnings("unchecked")
        Dictionary<String, Object> dictionary = ConfigurationHandler.read(stream);
        Assert.assertEquals(1, dictionary.size());
        Assert.assertEquals( "com.adobe.granite.foo.Bar", dictionary.get(SERVICE_PID));
    }

    @Test
    public void test_readElementWithWhitespaceAfterEQ() throws IOException {
        String entry = "service.pid=  \"com.adobe.granite.foo.Bar\"\r\n";
        InputStream stream = new ByteArrayInputStream(entry.getBytes(StandardCharsets.UTF_8));
        @SuppressWarnings("unchecked")
        Dictionary<String, Object> dictionary = ConfigurationHandler.read(stream);
        Assert.assertEquals(1, dictionary.size());
        Assert.assertEquals("com.adobe.granite.foo.Bar", dictionary.get(SERVICE_PID));
    }

    @Test
    public void test_readElementWithWhitespaceBeforeKey() throws IOException {
        String entry = "  service.pid=\"com.adobe.granite.foo.Bar\"\r\n";
        InputStream stream = new ByteArrayInputStream(entry.getBytes(StandardCharsets.UTF_8));
        @SuppressWarnings("unchecked")
        Dictionary<String, Object> dictionary = ConfigurationHandler.read(stream);
        Assert.assertEquals(1, dictionary.size());
        Assert.assertEquals("com.adobe.granite.foo.Bar", dictionary.get(SERVICE_PID));
    }
}

