/*
 * 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.sling.installer.factories.configuration.impl;

import java.io.IOException;
import java.lang.reflect.Array;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Set;

import org.osgi.framework.Constants;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.service.cm.Configuration;
import org.osgi.service.cm.ConfigurationAdmin;

/**
 * Utilities for configuration handling
 */
abstract class ConfigUtil {

    /**
     * This property marks the configuration as being deleted.
     */
    public static final String PROPERTY_DELETE_MARKER = "org.apache.sling.installer.configuration.deleted";

    /**
     * This property has been used in older versions to keep track where the
     * configuration has been installed from.
     */
    private static final String CONFIG_PATH_KEY = "org.apache.sling.installer.osgi.path";

    /**
     * This property has been used in older versions to keep track of factory
     * configurations.
     */
    private static final String ALIAS_KEY = "org.apache.sling.installer.osgi.factoryaliaspid";

    /** Configuration properties to ignore when comparing configs */
    private static final Set<String> IGNORED_PROPERTIES = new HashSet<String>();
    static {
        IGNORED_PROPERTIES.add(Constants.SERVICE_PID);
        IGNORED_PROPERTIES.add(CONFIG_PATH_KEY);
        IGNORED_PROPERTIES.add(ALIAS_KEY);
        IGNORED_PROPERTIES.add(ConfigurationAdmin.SERVICE_FACTORYPID);
    }

    private static Set<String> collectKeys(final Dictionary<String, Object>a) {
        final Set<String> keys = new HashSet<String>();
        final Enumeration<String> aI = a.keys();
        while (aI.hasMoreElements() ) {
            final String key = aI.nextElement();
            if ( !IGNORED_PROPERTIES.contains(key) ) {
                keys.add(key);
            }
        }
        return keys;
    }

    /**
     * Convert the object to an array
     * @param value The array
     * @return an object array
     */
    private static Object[] convertToObjectArray(final Object value) {
        final Object[] values = new Object[Array.getLength(value)];
        for(int i=0;i<values.length;i++) {
            values[i] = Array.get(value, i);
        }
        return values;
    }

    /** True if a and b represent the same config data, ignoring "non-configuration" keys in the dictionaries */
    public static boolean isSameData(Dictionary<String, Object>a, Dictionary<String, Object>b) {
        boolean result = false;
        if (a != null && b != null) {
            final Set<String> keysA = collectKeys(a);
            final Set<String> keysB = collectKeys(b);
            if ( keysA.size() == keysB.size() && keysA.containsAll(keysB) ) {
                result = true;
                for(final String key : keysA ) {
                    final Object valA = a.get(key);
                    final Object valB = b.get(key);
                    if ( valA.getClass().isArray() ) {
                        final Object[] arrA = convertToObjectArray(valA);
                        final Object[] arrB = convertToObjectArray(valB);

                        if ( arrA.length != arrB.length ) {
                            result = false;
                            break;
                        }
                        for(int i=0; i<arrA.length; i++) {
                            if ( !(String.valueOf(arrA[i]).equals(String.valueOf(arrB[i]))) ) {
                                result = false;
                                break;
                            }
                        }
                    } else {
                        // we always do a string comparison
                        if ( !(String.valueOf(valA).equals(String.valueOf(valB))) ) {
                            result = false;
                            break;
                        }
                    }
                }
            }
        }
        return result;
    }

    /**
     * Remove all ignored properties
     */
    public static Dictionary<String, Object> cleanConfiguration(final Dictionary<String, Object> config) {
        final Dictionary<String, Object> cleanedConfig = new Hashtable<String, Object>();
        final Enumeration<String> e = config.keys();
        while(e.hasMoreElements()) {
            final String key = e.nextElement();
            if ( !IGNORED_PROPERTIES.contains(key) ) {
                cleanedConfig.put(key, config.get(key));
            }
        }

        return cleanedConfig;
    }

    /**
     * Encode the value for the ldap filter: \, *, (, and ) should be escaped.
     */
    private static String encode(final String value) {
        return value.replace("\\", "\\\\")
                .replace("*", "\\*")
                .replace("(", "\\(")
                .replace(")", "\\)");
    }

    public static Configuration getConfiguration(final ConfigurationAdmin ca,
            final String factoryPid,
            final String configPid)
    throws IOException, InvalidSyntaxException {
        return getOrCreateConfiguration(ca, factoryPid, configPid, null, false);
    }

    public static Configuration createConfiguration(final ConfigurationAdmin ca,
            final String factoryPid,
            final String configPid,
            final String location)
    throws IOException, InvalidSyntaxException {
        return getOrCreateConfiguration(ca, factoryPid, configPid, location, true);
    }

    private static Configuration getOrCreateConfiguration(final ConfigurationAdmin ca,
            final String factoryPid,
            final String configPid,
            final String location,
            final boolean createIfNeeded)
    throws IOException, InvalidSyntaxException {
        Configuration result = null;

        if (factoryPid == null) {
            if (createIfNeeded) {
                result = ca.getConfiguration(configPid, location);
            } else {
                String filter = "(" + Constants.SERVICE_PID + "=" + encode(configPid)
                        + ")";
                Configuration[] configs = ca.listConfigurations(filter);
                if (configs != null && configs.length > 0) {
                    result = configs[0];
                }
            }
        } else {
            Configuration configs[] = null;
            if ( configPid != null ) {
                configs = ca.listConfigurations("(&("
                        + ConfigurationAdmin.SERVICE_FACTORYPID + "=" + encode(factoryPid)
                        + ")(" + Constants.SERVICE_PID + "=" + encode(configPid)
                        + "))");
            }
            if (configs == null || configs.length == 0) {
                configs = ca.listConfigurations("(&("
                        + ConfigurationAdmin.SERVICE_FACTORYPID + "=" + encode(factoryPid)
                        + ")(" + Constants.SERVICE_PID + "=" + encode(factoryPid + "." + configPid)
                        + "))");
            }
            if (configs == null || configs.length == 0) {
                // check for old style with alias pid
                configs = ca.listConfigurations(
                        "(&(" + ConfigurationAdmin.SERVICE_FACTORYPID
                        + "=" + factoryPid + ")(" + ALIAS_KEY + "=" + encode(configPid)
                        + "))");

                if (configs == null || configs.length == 0) {
                    if (createIfNeeded) {
                        result = ca.createFactoryConfiguration(factoryPid, location);
                    }
                } else {
                    result = configs[0];
                }
            } else {
                result = configs[0];
            }
        }

        return result;
    }

    public static boolean toBoolean(final Object obj, final boolean defaultValue) {
        boolean result = defaultValue;
        if ( obj != null ) {
            if (obj instanceof Boolean) {
                result = ((Boolean) obj).booleanValue();
            } else {
                result = Boolean.valueOf(String.valueOf(obj));
            }
        }
        return result;
    }
}
