/*
 * Copyright 2017 HugeGraph Authors
 *
 * 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.hugegraph.unit.config;

import static org.apache.hugegraph.config.OptionChecker.allowValues;
import static org.apache.hugegraph.config.OptionChecker.disallowEmpty;
import static org.apache.hugegraph.config.OptionChecker.inValues;
import static org.apache.hugegraph.config.OptionChecker.nonNegativeInt;
import static org.apache.hugegraph.config.OptionChecker.positiveInt;
import static org.apache.hugegraph.config.OptionChecker.rangeDouble;
import static org.apache.hugegraph.config.OptionChecker.rangeInt;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.hugegraph.config.ConfigConvOption;
import org.apache.hugegraph.config.ConfigException;
import org.apache.hugegraph.config.ConfigListConvOption;
import org.apache.hugegraph.config.ConfigListOption;
import org.apache.hugegraph.config.ConfigOption;
import org.apache.hugegraph.config.HugeConfig;
import org.apache.hugegraph.config.OptionHolder;
import org.apache.hugegraph.config.OptionSpace;
import org.apache.hugegraph.testutil.Assert;
import org.apache.hugegraph.unit.BaseUnitTest;
import org.apache.commons.collections.IteratorUtils;
import org.apache.commons.configuration2.AbstractConfiguration;
import org.apache.commons.configuration2.Configuration;
import org.apache.commons.configuration2.MapConfiguration;
import org.apache.commons.configuration2.PropertiesConfiguration;
import org.apache.commons.configuration2.convert.DisabledListDelimiterHandler;
import org.apache.commons.configuration2.ex.ConfigurationException;
import org.apache.commons.configuration2.io.FileHandler;
import org.apache.commons.io.FileUtils;
import org.junit.BeforeClass;
import org.junit.Test;

import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;

public class HugeConfigTest extends BaseUnitTest {

    private static final String PATH =
                         "src/test/java/org/apache/hugegraph/unit/config/";
    private static final String CONF = PATH + "test.conf";

    @BeforeClass
    public static void init() {
        OptionSpace.register("test", TestOptions.class.getName());
    }

    @Test
    public void testOptionDataType() {
        Assert.assertEquals(String.class, TestOptions.text1.dataType());
        Assert.assertEquals(Integer.class, TestOptions.int1.dataType());
        Assert.assertEquals(Long.class, TestOptions.long1.dataType());
        Assert.assertEquals(Float.class, TestOptions.float1.dataType());
        Assert.assertEquals(Double.class, TestOptions.double1.dataType());
        Assert.assertEquals(Boolean.class, TestOptions.bool.dataType());

        Assert.assertEquals(Class.class, TestOptions.clazz.dataType());

        Assert.assertEquals(List.class, TestOptions.list.dataType());
        Assert.assertEquals(List.class, TestOptions.map.dataType());

        Assert.assertEquals(String.class, TestOptions.weekday.dataType());
        Assert.assertEquals(List.class, TestOptions.weekdays.dataType());
    }

    @Test
    public void testOptionDesc() {
        Assert.assertEquals("description of group1.text1",
                            TestOptions.text1.desc());
        Assert.assertEquals("description of group1.text2 sub",
                            TestSubOptions.text2.desc());
    }

    @Test
    public void testOptionRequired() {
        Assert.assertEquals(false, TestOptions.text1.required());
        Assert.assertEquals(true, TestSubOptions.text2.required());
    }

    @Test
    public void testOptionsToString() {
        Assert.assertEquals("[String]group1.text1=text1-value",
                            TestOptions.text1.toString());
        Assert.assertEquals("[Integer]group1.int1=1",
                            TestOptions.int1.toString());
        Assert.assertEquals("[Long]group1.long1=100",
                            TestOptions.long1.toString());
        Assert.assertEquals("[Float]group1.float1=100.0",
                            TestOptions.float1.toString());
        Assert.assertEquals("[Double]group1.double1=100.0",
                            TestOptions.double1.toString());
        Assert.assertEquals("[Boolean]group1.bool=true",
                            TestOptions.bool.toString());
        Assert.assertEquals("[Class]group1.class=class java.lang.Object",
                            TestOptions.clazz.toString());
        Assert.assertEquals("[List]group1.list=[list-value1, list-value2]",
                            TestOptions.list.toString());
        Assert.assertEquals("[List]group1.map=[key1:value1, key2:value2]",
                            TestOptions.map.toString());

        Assert.assertEquals("[String]group1.text1=text1-value",
                            TestSubOptions.text1.toString());
        Assert.assertEquals("[String]group1.text2=text2-value-override",
                            TestSubOptions.text2.toString());
        Assert.assertEquals("[String]group1.textsub=textsub-value",
                            TestSubOptions.textsub.toString());
    }

    @Test
    public void testOptionWithError() {
        Assert.assertThrows(ConfigException.class, () -> {
            new ConfigOption<>(
                    "group1.text",
                    "description of group1.text",
                    disallowEmpty(),
                    ""
            );
        });

        Assert.assertThrows(ConfigException.class, () -> {
            new ConfigOption<>(
                    "group1.choice",
                    "description of group1.choice",
                    allowValues("CHOICE-1", "CHOICE-2", "CHOICE-3"),
                    "CHOICE-4"
            );
        });

        Assert.assertThrows(ConfigException.class, () -> {
            new ConfigListOption<>(
                    "group1.list",
                    true,
                    "description of group1.list",
                    disallowEmpty(),
                    String.class,
                    ImmutableList.of()
            );
        });

        Assert.assertThrows(ConfigException.class, () -> {
            new ConfigOption<>(
                    "group1.int",
                    "description of group1.int",
                    positiveInt(),
                    0
            );
        });

        Assert.assertThrows(ConfigException.class, () -> {
            new ConfigOption<>(
                    "group1.int",
                    "description of group1.int",
                    nonNegativeInt(),
                    -1
            );
        });

        Assert.assertThrows(ConfigException.class, () -> {
            new ConfigOption<>(
                    "group1.long",
                    "description of group1.long",
                    rangeInt(1L, 100L),
                    0L
            );
        });

        Assert.assertThrows(ConfigException.class, () -> {
            new ConfigOption<>(
                    "group1.long",
                    "description of group1.long",
                    rangeInt(1L, 100L),
                    101L
            );
        });

        Assert.assertThrows(ConfigException.class, () -> {
            new ConfigOption<>(
                    "group1.double",
                    "description of group1.double",
                    rangeDouble(1D, 10D),
                    0D
            );
        });

        Assert.assertThrows(ConfigException.class, () -> {
            new ConfigOption<>(
                    "group1.double",
                    "description of group1.double",
                    rangeDouble(1D, 10D),
                    11D
            );
        });

        Assert.assertThrows(ConfigException.class, () -> {
            new ConfigOption<>(
                    "group1.class",
                    "description of group1.class",
                    input -> input != null && input.equals(Long.class),
                    Integer.class
            );
        });

        Assert.assertThrows(ConfigException.class, () -> {
            new ConfigListOption<>(
                    "group1.list",
                    "description of list with invalid default values",
                    disallowEmpty()
            );
        });

        Assert.assertThrows(IllegalArgumentException.class, () -> {
            new ConfigListOption<>(
                    "group1.list",
                    "description of list with invalid default values",
                    null
            );
        });

        Assert.assertThrows(ConfigException.class, () -> {
            new ConfigListConvOption<String, WeekDay>(
                    "group1.list_conv",
                    "description of list_conv with invalid default values",
                    disallowEmpty(),
                    s -> WeekDay.valueOf(s)
            );
        });

        Assert.assertThrows(IllegalArgumentException.class, () -> {
            new ConfigListConvOption<String, WeekDay>(
                    "group1.list_conv",
                    "description of list_conv with invalid default values",
                    null,
                    s -> WeekDay.valueOf(s)
            );
        });
    }

    @Test
    public void testHugeConfig() throws Exception {
        Configuration conf = new PropertiesConfiguration();
        Assert.assertEquals(DisabledListDelimiterHandler.INSTANCE,
               ((AbstractConfiguration) conf).getListDelimiterHandler());

        HugeConfig config = new HugeConfig(conf);

        Assert.assertEquals("text1-value", config.get(TestOptions.text1));
        Assert.assertEquals("text2-value", config.get(TestOptions.text2));
        Assert.assertEquals("CHOICE-1", config.get(TestOptions.text3));

        Assert.assertEquals(1, (int) config.get(TestOptions.int1));
        Assert.assertEquals(10, (int) config.get(TestOptions.int2));
        Assert.assertEquals(10, (int) config.get(TestOptions.int3));

        Assert.assertEquals(100L, (long) config.get(TestOptions.long1));

        Assert.assertEquals(100.0f, config.get(TestOptions.float1), 0f);
        Assert.assertEquals(100.0f, config.get(TestOptions.double1), 0d);

        Assert.assertEquals(true, config.get(TestOptions.bool));

        Assert.assertEquals(Object.class, config.get(TestOptions.clazz));
        Assert.assertThrows(ConfigException.class, () -> {
            config.setProperty(TestOptions.clazz.name(),
                               "org.apache.hugegraph.HugeGraph");
        }, e -> {
            Assert.assertTrue(e.getCause() instanceof ClassNotFoundException);
        });

        Assert.assertEquals(Arrays.asList("list-value1", "list-value2"),
                            config.get(TestOptions.list));

        Assert.assertEquals(ImmutableMap.of("key1", "value1", "key2", "value2"),
                            config.getMap(TestOptions.map));

        Assert.assertEquals(WeekDay.WEDNESDAY, config.get(TestOptions.weekday));
        Assert.assertEquals(Arrays.asList(WeekDay.SATURDAY, WeekDay.SUNDAY),
                            config.get(TestOptions.weekdays));

        Assert.assertThrows(ConfigException.class, () -> {
            new HugeConfig((Configuration) null);
        });
    }

    @Test
    public void testHugeConfigWithFile() throws Exception {
        HugeConfig config = new HugeConfig(CONF);

        Assert.assertEquals("file-text1-value", config.get(TestOptions.text1));
        Assert.assertEquals("file-text2-value", config.get(TestOptions.text2));
        Assert.assertEquals("CHOICE-3", config.get(TestOptions.text3));

        Assert.assertEquals(2, (int) config.get(TestOptions.int1));
        Assert.assertEquals(0, (int) config.get(TestOptions.int2));
        Assert.assertEquals(1, (int) config.get(TestOptions.int3));

        Assert.assertEquals(99L, (long) config.get(TestOptions.long1));

        Assert.assertEquals(66.0f, config.get(TestOptions.float1), 0f);
        Assert.assertEquals(66.0f, config.get(TestOptions.double1), 0d);

        Assert.assertEquals(false, config.get(TestOptions.bool));

        Assert.assertEquals(String.class, config.get(TestOptions.clazz));

        Assert.assertEquals(Arrays.asList("file-v1", "file-v2", "file-v3"),
                            config.get(TestOptions.list));

        Assert.assertEquals(ImmutableMap.of("key1", "value1", "key3", "value3"),
                            config.getMap(TestOptions.map));

        Assert.assertEquals(WeekDay.SUNDAY, config.get(TestOptions.weekday));
        Assert.assertEquals(Arrays.asList(WeekDay.SATURDAY, WeekDay.FRIDAY),
                            config.get(TestOptions.weekdays));
    }

    @Test
    public void testHugeConfigWithConfiguration() throws Exception {
        PropertiesConfiguration configuration = new PropertiesConfiguration();
        FileHandler fileHandler = new FileHandler(configuration);
        fileHandler.load(CONF);
        HugeConfig config = new HugeConfig(configuration);

        Assert.assertEquals("file-text1-value", config.get(TestOptions.text1));
        Assert.assertEquals("file-text2-value", config.get(TestOptions.text2));
        Assert.assertEquals("CHOICE-3", config.get(TestOptions.text3));
    }

    @Test
    public void testHugeConfigWithOverride() throws Exception {
        Configuration conf = new PropertiesConfiguration();
        Assert.assertEquals(DisabledListDelimiterHandler.INSTANCE,
               ((AbstractConfiguration) conf).getListDelimiterHandler());

        HugeConfig config = new HugeConfig(conf);

        Assert.assertEquals("text1-value", config.get(TestSubOptions.text1));

        Assert.assertEquals("text2-value-override",
                            config.get(TestSubOptions.text2));
        Assert.assertEquals("textsub-value",
                            config.get(TestSubOptions.textsub));
    }

    @Test
    public void testHugeConfigWithTypeError() {
        OptionSpace.register("test-type-error",
                             TestOptionsWithTypeError.class.getName());

        Assert.assertThrows(ConfigException.class, () -> {
            new HugeConfig(PATH + "test-type-error.conf");
        });
    }

    @Test
    public void testHugeConfigWithCheckError() throws Exception {
        OptionSpace.register("test-check-error",
                             TestOptionsWithCheckError.class.getName());

        Assert.assertThrows(ConfigException.class, () -> {
            new HugeConfig(PATH + "test-check-error.conf");
        });
    }

    @Test
    public void testHugeConfigWithListOptionError() throws Exception {
        OptionSpace.register("test-list-error",
                             TestOptionsWithListError.class.getName());

        Assert.assertThrows(IllegalStateException.class, () -> {
            new HugeConfig(PATH + "test-list-error.conf");
        });
    }

    @Test
    public void testSaveHugeConfig() throws ConfigurationException,
                                            IOException {
        HugeConfig config = new HugeConfig(CONF);
        Assert.assertEquals("file-text1-value", config.get(TestOptions.text1));

        File copiedFile = new File("copied.conf");
        config.save(copiedFile);
        Assert.assertTrue(copiedFile.exists());
        Assert.assertTrue(copiedFile.length() > 0);

        try {
            HugeConfig copiedConfig = new HugeConfig(copiedFile.getPath());
            Assert.assertEquals(IteratorUtils.toList(config.getKeys()),
                                IteratorUtils.toList(copiedConfig.getKeys()));
            Assert.assertEquals(config.get(TestOptions.text1),
                                copiedConfig.get(TestOptions.text1));
        } finally {
            FileUtils.forceDelete(copiedFile);
        }
    }

    @Test
    public void testFromMapConfigurationWithList() {
        Map<String, String> options = new HashMap<>();
        options.put(TestOptions.list.name(), "[a, b]");
        MapConfiguration mapConfiguration = new MapConfiguration(options);
        HugeConfig hugeConfig = new HugeConfig(mapConfiguration);
        List<String> values = hugeConfig.get(TestOptions.list);
        Assert.assertEquals(2, values.size());
        Assert.assertTrue(values.contains("a"));
        Assert.assertTrue(values.contains("b"));
    }

    public static class TestOptions extends OptionHolder {

        private static volatile TestOptions instance;

        public static synchronized TestOptions instance() {
            if (instance == null) {
                instance = new TestOptions();
                instance.registerOptions();
            }
            return instance;
        }

        public static final ConfigOption<String> text1 =
                new ConfigOption<>(
                        "group1.text1",
                        "description of group1.text1",
                        disallowEmpty(),
                        "text1-value"
                );

        public static final ConfigOption<String> text2 =
                new ConfigOption<>(
                        "group1.text2",
                        "description of group1.text2",
                        "text2-value"
                );

        public static final ConfigOption<String> text3 =
                new ConfigOption<>(
                        "group1.text3",
                        "description of group1.text3",
                        allowValues("CHOICE-1", "CHOICE-2", "CHOICE-3"),
                        "CHOICE-1"
                );

        public static final ConfigOption<Integer> int1 =
                new ConfigOption<>(
                        "group1.int1",
                        "description of group1.int1",
                        rangeInt(1, 100),
                        1
                );

        public static final ConfigOption<Integer> int2 =
                new ConfigOption<>(
                        "group1.int2",
                        "description of group1.int2",
                        nonNegativeInt(),
                        10
                );

        public static final ConfigOption<Integer> int3 =
                new ConfigOption<>(
                        "group1.int3",
                        "description of group1.int3",
                        positiveInt(),
                        10
                );

        public static final ConfigOption<Long> long1 =
                new ConfigOption<>(
                        "group1.long1",
                        "description of group1.long1",
                        rangeInt(1L, 100L),
                        100L
                );

        public static final ConfigOption<Float> float1 =
                new ConfigOption<>(
                        "group1.float1",
                        "description of group1.float1",
                        rangeDouble(1.0f, 100.0f),
                        100.0f
                );

        public static final ConfigOption<Double> double1 =
                new ConfigOption<>(
                        "group1.double1",
                        "description of group1.double1",
                        rangeDouble(1.0, 100.0),
                        100.0
                );

        public static final ConfigOption<Boolean> bool =
                new ConfigOption<>(
                        "group1.bool",
                        "description of group1.bool",
                        disallowEmpty(),
                        true
                );

        public static final ConfigOption<Class<?>> clazz =
                new ConfigOption<>(
                        "group1.class",
                        "description of group1.class",
                        disallowEmpty(),
                        Object.class
                );

        public static final ConfigConvOption<String, WeekDay> weekday =
                new ConfigConvOption<>(
                        "group1.weekday",
                        "description of group1.weekday",
                        allowValues("SUNDAY", "MONDAY", "TUESDAY", "WEDNESDAY",
                                    "THURSDAY", "FRIDAY", "SATURDAY"),
                        WeekDay::valueOf,
                        "WEDNESDAY"
                );

        public static final ConfigListConvOption<String, WeekDay> weekdays =
                new ConfigListConvOption<>(
                        "group1.weekdays",
                        "description of group1.weekdays",
                        inValues("SUNDAY", "MONDAY", "TUESDAY", "WEDNESDAY",
                                 "THURSDAY", "FRIDAY", "SATURDAY"),
                        WeekDay::valueOf,
                        "SATURDAY", "SUNDAY"
                );

        public static final ConfigListOption<String> list =
                new ConfigListOption<>(
                        "group1.list",
                        "description of group1.list",
                        disallowEmpty(),
                        "list-value1", "list-value2"
                );

        public static final ConfigListOption<String> map =
                new ConfigListOption<>(
                        "group1.map",
                        "description of group1.map",
                        disallowEmpty(),
                        "key1:value1", "key2:value2"
                );
    }

    public static class TestSubOptions extends TestOptions {

        public static final ConfigOption<String> text2 =
                new ConfigOption<>(
                        "group1.text2",
                        true,
                        "description of group1.text2 sub",
                        disallowEmpty(),
                        String.class,
                        "text2-value-override"
                );

        public static final ConfigOption<String> textsub =
                new ConfigOption<>(
                        "group1.textsub",
                        "description of group1.textsub",
                        disallowEmpty(),
                        "textsub-value"
                );
    }

    public static class TestOptionsWithTypeError extends OptionHolder {

        private static volatile TestOptionsWithTypeError instance;

        public static synchronized TestOptionsWithTypeError instance() {
            if (instance == null) {
                instance = new TestOptionsWithTypeError();
                instance.registerOptions();
            }
            return instance;
        }

        public static final ConfigOption<Integer> intError =
                new ConfigOption<>(
                        "group1.int_type_error",
                        "description of group1.int_type_error",
                        rangeInt(1, 100),
                        1
                );
    }

    public static class TestOptionsWithCheckError extends OptionHolder {

        private static volatile TestOptionsWithCheckError instance;

        public static synchronized TestOptionsWithCheckError instance() {
            if (instance == null) {
                instance = new TestOptionsWithCheckError();
                instance.registerOptions();
            }
            return instance;
        }

        public static final ConfigOption<Integer> intError =
                new ConfigOption<>(
                        "group1.int_check_error",
                        "description of group1.int_check_error",
                        rangeInt(1, 100),
                        1
                );
    }

    public static class TestOptionsWithListError extends OptionHolder {

        private static volatile TestOptionsWithListError instance;

        public static synchronized TestOptionsWithListError instance() {
            if (instance == null) {
                instance = new TestOptionsWithListError();
                instance.registerOptions();
            }
            return instance;
        }

        public static final InvalidConfigListOption<Integer> listError =
                new InvalidConfigListOption<>(
                        "group1.list_for_list_error",
                        "description of group1.list_for_list_error",
                        disallowEmpty(),
                        1
                );

        static class InvalidConfigListOption<T> extends ConfigOption<List<T>> {

            @SuppressWarnings("unchecked")
            public InvalidConfigListOption(String name, String desc,
                                           Predicate<List<T>> pred,
                                           T... values) {
                super(name, false, desc, pred,
                      (Class<List<T>>) Arrays.asList(values).getClass(),
                      Arrays.asList(values));
            }

            @Override
            protected boolean forList() {
                return false;
            }
        }
    }

    public enum WeekDay {

        SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY;
    }
}
