/*
 * Copyright (C) 2016 Charles Brophy
 *
 * Licensed 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.granite.configuration;

import com.google.common.base.CharMatcher;

import org.granite.base.StringTools;

import java.io.Serializable;
import java.util.Map;
import java.util.function.Function;
import java.util.logging.Logger;

import static com.google.common.base.Preconditions.checkNotNull;

public final class ApplicationConfiguration implements Serializable {

    private final Map<String, String> configMap;

    ApplicationConfiguration(final Map<String, String> configMap) {
        this.configMap = checkNotNull(configMap, "configMap");
    }

    public Map<String, String> getConfigMap() {
        return configMap;
    }

    public int getInt(final String configKey) {
        return Integer.valueOf(getString(configKey));
    }

    public int getInt(final String configKey, final int defaultValue) {
        final String configValueString = getString(configKey, null);

        return configValueString == null ? defaultValue : Integer.valueOf(configValueString);
    }

    public long getLong(final String configKey) {
        return Long.valueOf(getString(configKey));
    }

    public long getLong(final String configKey, final long defaultValue) {
        final String configValueString = getString(configKey, null);

        return configValueString == null ? defaultValue : Long.valueOf(configValueString);
    }

    public double getDouble(final String configKey) {
        return Double.valueOf(getString(configKey));
    }

    public double getDouble(final String configKey, final double defaultValue) {
        final String configValueString = getString(configKey, null);

        return configValueString == null ? defaultValue : Double.valueOf(configValueString);
    }

    public boolean getBoolean(final String configKey) {
        return Boolean.valueOf(getString(configKey));
    }

    public boolean getBoolean(final String configKey, final boolean defaultValue) {
        final String configValueString = getString(configKey, null);

        return configValueString == null ? defaultValue : Boolean.valueOf(configValueString);
    }

    public String getString(final String configKey) {
        checkNotNull(configKey, "configKey");

        final String configValueString = configMap.get(configKey);

        checkNotNull(configValueString, "Required config key %s not present", configKey);

        return configValueString;
    }

    public String getString(final String configKey, final String defaultValue) {
        checkNotNull(configKey, "configKey");

        final String configValueString = configMap.get(configKey);

        return configValueString == null ? defaultValue : configValueString;
    }

    public <V> V getValue(final String configKey,
                          final V defaultValue,
                          final Function<String, V> valueConverter) {
        final String configValueString = configMap.get(configKey);

        return configValueString == null ? defaultValue : valueConverter.apply(configValueString);

    }

    public <V> Map<String, V> getMap(final String configKey,
                                     final CharMatcher entryDelimiter,
                                     final CharMatcher keyValueDelimiter,
                                     final Function<String, V> valueConverter) {
        return StringTools
                .convertStringsToMap(
                        getString(configKey, ""),
                        entryDelimiter,
                        keyValueDelimiter,
                        valueConverter,
                        true
                );
    }

    public boolean isSet(final String configKey) {
        checkNotNull(configKey, "configKey");

        return !StringTools.isNullOrEmpty(configMap.get(configKey));
    }

    public void printConfig() {
        if (configMap.isEmpty()) {
            Logger.getGlobal().info("No configuration loaded");
        }

        configMap
                .keySet()
                .forEach(key -> Logger.getGlobal()
                        .info(String.format("%s = %s", key, configMap.get(key))));
    }

}

@@ -669,16 +669,104 @@
 Matcher;
+%0Aimport com.google.common.base.Splitter;%0Aimport com.google.common.collect.ImmutableList;
 %0A%0Aimport
@@ -826,16 +826,39 @@
 izable;%0A
+import java.util.List;%0A
 import j
@@ -907,16 +907,16 @@
 nction;%0A
-
 import j
@@ -939,16 +939,52 @@
 .Logger;
+%0Aimport java.util.stream.Collectors;
 %0A%0Aimport
@@ -4319,32 +4319,929 @@
       );%0A    %7D%0A%0A
+    public %3CV%3E List%3CV%3E getList(final String configKey,%0A                               final CharMatcher entryDelimiter,%0A                               final Function%3CString, V%3E valueConverter) %7B%0A        final String configValueString = getString(configKey, %22%22);%0A%0A        if (StringTools.isNullOrEmpty(configValueString)) return ImmutableList.of();%0A%0A        return Splitter%0A                .on(entryDelimiter)%0A                .omitEmptyStrings()%0A                .trimResults()%0A                .splitToList(configValueString)%0A                .stream()%0A                .map(valueConverter)%0A                .collect(Collectors.toList());%0A    %7D%0A%0A    public List%3CString%3E getList(final String configKey,%0A                                final CharMatcher entryDelimiter) %7B%0A        return getList(%0A                configKey,%0A                entryDelimiter,%0A                value -%3E value%0A        );%0A    %7D%0A%0A
     public boole
@@ -5635,16 +5635,30 @@
 lobal()%0A
+              
         

Add list getter to config class