/**
 * 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.atlas.security;

import org.apache.atlas.AtlasException;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.configuration.ConfigurationConverter;
import org.apache.commons.lang.ArrayUtils;
import org.apache.hadoop.security.SecurityUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.security.auth.login.AppConfigurationEntry;
import javax.security.auth.login.Configuration;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.SortedSet;
import java.util.StringTokenizer;
import java.util.TreeSet;


/**
 * InMemoryJAASConfiguration
 *
 * An utility class - which has a static method init to load all JAAS configuration from Application
 * properties file (eg: atlas.properties) and set it as part of the default lookup configuration for
 * all JAAS configuration lookup.
 *
 * Example settings in jaas-application.properties:
 *
 * atlas.jaas.KafkaClient.loginModuleName = com.sun.security.auth.module.Krb5LoginModule
 * atlas.jaas.KafkaClient.loginModuleControlFlag = required
 * atlas.jaas.KafkaClient.option.useKeyTab = true
 * atlas.jaas.KafkaClient.option.storeKey = true
 * atlas.jaas.KafkaClient.option.serviceName = kafka
 * atlas.jaas.KafkaClient.option.keyTab = /etc/security/keytabs/kafka_client.keytab
 * atlas.jaas.KafkaClient.option.principal = kafka-client-1@EXAMPLE.COM

 * atlas.jaas.MyClient.0.loginModuleName = com.sun.security.auth.module.Krb5LoginModule
 * atlas.jaas.MyClient.0.loginModuleControlFlag = required
 * atlas.jaas.MyClient.0.option.useKeyTab = true
 * atlas.jaas.MyClient.0.option.storeKey = true
 * atlas.jaas.MyClient.0.option.serviceName = kafka
 * atlas.jaas.MyClient.0.option.keyTab = /etc/security/keytabs/kafka_client.keytab
 * atlas.jaas.MyClient.0.option.principal = kafka-client-1@EXAMPLE.COM
 * atlas.jaas.MyClient.1.loginModuleName = com.sun.security.auth.module.Krb5LoginModule
 * atlas.jaas.MyClient.1.loginModuleControlFlag = optional
 * atlas.jaas.MyClient.1.option.useKeyTab = true
 * atlas.jaas.MyClient.1.option.storeKey = true
 * atlas.jaas.MyClient.1.option.serviceName = kafka
 * atlas.jaas.MyClient.1.option.keyTab = /etc/security/keytabs/kafka_client.keytab
 * atlas.jaas.MyClient.1.option.principal = kafka-client-1@EXAMPLE.COM

 * This will set the JAAS configuration - equivalent to the jaas.conf file entries:
 *  KafkaClient {
 *      com.sun.security.auth.module.Krb5LoginModule required
 *          useKeyTab=true
 *          storeKey=true
 *          serviceName=kafka
 *          keyTab="/etc/security/keytabs/kafka_client.keytab"
 *          principal="kafka-client-1@EXAMPLE.COM";
 *  };
 *  MyClient {
 *      com.sun.security.auth.module.Krb5LoginModule required
 *          useKeyTab=true
 *          storeKey=true
 *          serviceName=kafka keyTab="/etc/security/keytabs/kafka_client.keytab"
 *          principal="kafka-client-1@EXAMPLE.COM";
 *  };
 *  MyClient {
 *      com.sun.security.auth.module.Krb5LoginModule optional
 *          useKeyTab=true
 *          storeKey=true
 *          serviceName=kafka
 *          keyTab="/etc/security/keytabs/kafka_client.keytab"
 *          principal="kafka-client-1@EXAMPLE.COM";
 *  };
 *
 *  Here is the syntax for atlas.properties to add JAAS configuration:
 *
 *  The property name has to begin with   'atlas.jaas.' +  clientId (in case of Kafka client,
 *  it expects the clientId to be  KafkaClient).
 *  The following property must be there to specify the JAAS loginModule name
 *          'atlas.jaas.' +  clientId  + '.loginModuleName'
 *  The following optional property should be set to specify the loginModuleControlFlag
 *          'atlas.jaas.' + clientId + '.loginModuleControlFlag'
 *          Default value :  required ,  Possible values:  required, optional, sufficient, requisite
 *  Then you can add additional optional parameters as options for the configuration using the following
 *  syntax:
 *          'atlas.jaas.' + clientId + '.option.' + <optionName>  = <optionValue>
 *
 *  The current setup will lookup JAAS configration from the atlas-application.properties first, if not available,
 *  it will delegate to the original configuration
 *
 */


public final class InMemoryJAASConfiguration extends Configuration {

    private static final Logger LOG = LoggerFactory.getLogger(InMemoryJAASConfiguration.class);

    private static final String JAAS_CONFIG_PREFIX_PARAM = "atlas.jaas.";
    private static final String JAAS_CONFIG_LOGIN_MODULE_NAME_PARAM = "loginModuleName";
    private static final String JAAS_CONFIG_LOGIN_MODULE_CONTROL_FLAG_PARAM = "loginModuleControlFlag";
    private static final String JAAS_CONFIG_LOGIN_OPTIONS_PREFIX = "option";
    private static final String JAAS_PRINCIPAL_PROP = "principal";
    private static final Map<String, String> CONFIG_SECTION_REDIRECTS = new HashMap<>();

    private Configuration parent = null;
    private Map<String, List<AppConfigurationEntry>> applicationConfigEntryMap = new HashMap<>();

    public static void init(String propFile) throws AtlasException {
        if (LOG.isDebugEnabled()) {
            LOG.debug("==> InMemoryJAASConfiguration.init({})", propFile);
        }

        InputStream in = null;

        try {
            Properties properties = new Properties();
            in = ClassLoader.getSystemResourceAsStream(propFile);
            if (in == null) {
                if (!propFile.startsWith("/")) {
                    in = ClassLoader.getSystemResourceAsStream("/" + propFile);
                }
                if (in == null) {
                    in = new FileInputStream(new File(propFile));
                }
            }
            properties.load(in);
            init(properties);
        } catch (IOException e) {
            throw new AtlasException("Failed to load JAAS application properties", e);
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (Exception exception) {
                    // Ignore
                }
            }
        }

        if (LOG.isDebugEnabled()) {
            LOG.debug("<== InMemoryJAASConfiguration.init({})", propFile);
        }
    }

    public static void init(org.apache.commons.configuration.Configuration atlasConfiguration) throws AtlasException {
        LOG.debug("==> InMemoryJAASConfiguration.init()");

        if (atlasConfiguration != null && !atlasConfiguration.isEmpty()) {
            Properties properties = ConfigurationConverter.getProperties(atlasConfiguration);
            init(properties);
        } else {
            throw new AtlasException("Failed to load JAAS application properties: configuration NULL or empty!");
        }

        LOG.debug("<== InMemoryJAASConfiguration.init()");
    }

    public static void init(Properties properties) throws AtlasException {
        LOG.debug("==> InMemoryJAASConfiguration.init()");

        if (properties != null && MapUtils.isNotEmpty(properties)) {
            InMemoryJAASConfiguration conf = new InMemoryJAASConfiguration(properties);
            Configuration.setConfiguration(conf);
        } else {
            throw new AtlasException("Failed to load JAAS application properties: properties NULL or empty!");
        }

        LOG.debug("<== InMemoryJAASConfiguration.init()");
    }

    @Override
    public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("==> InMemoryJAASConfiguration.getAppConfigurationEntry({})", name);
        }

        AppConfigurationEntry[] ret = null;
        List<AppConfigurationEntry> retList = null;
        String redirectedName = getConfigSectionRedirect(name);

        if (redirectedName != null) {
            retList = applicationConfigEntryMap.get(redirectedName);

            if (LOG.isDebugEnabled()) {
                LOG.debug("Redirected jaasConfigSection ({} -> {}): ", name, redirectedName, retList);
            }
        }

        if (retList == null || retList.size() == 0) {
            retList = applicationConfigEntryMap.get(name);
        }

        if (retList == null || retList.size() == 0) {
            if (parent != null) {
                ret = parent.getAppConfigurationEntry(name);
            }
        } else {
            int sz = retList.size();
            ret = new AppConfigurationEntry[sz];
            ret = retList.toArray(ret);
        }

        if (LOG.isDebugEnabled()) {
            LOG.debug("<== InMemoryJAASConfiguration.getAppConfigurationEntry({}): {}", name, ArrayUtils.toString(ret));
        }

        return ret;
    }

    private InMemoryJAASConfiguration(Properties prop) {
        parent = Configuration.getConfiguration();
        initialize(prop);
    }

    private void initialize(Properties properties) {
        LOG.debug("==> InMemoryJAASConfiguration.initialize()");

        int prefixLen = JAAS_CONFIG_PREFIX_PARAM.length();

        Map<String, SortedSet<Integer>> jaasClients = new HashMap<>();
        for (String key : properties.stringPropertyNames()) {
            if (key.startsWith(JAAS_CONFIG_PREFIX_PARAM)) {
                String jaasKey = key.substring(prefixLen);
                StringTokenizer tokenizer = new StringTokenizer(jaasKey, ".");
                int tokenCount = tokenizer.countTokens();
                if (tokenCount > 0) {
                    String clientId = tokenizer.nextToken();
                    SortedSet<Integer> indexList = jaasClients.get(clientId);
                    if (indexList == null) {
                        indexList = new TreeSet<>();
                        jaasClients.put(clientId, indexList);
                    }
                    String indexStr = tokenizer.nextToken();

                    int indexId = isNumeric(indexStr) ? Integer.parseInt(indexStr) : -1;

                    Integer clientIdIndex = Integer.valueOf(indexId);

                    if (!indexList.contains(clientIdIndex)) {
                        indexList.add(clientIdIndex);
                    }

                }
            }
        }
        for (String jaasClient : jaasClients.keySet()) {

            for (Integer index : jaasClients.get(jaasClient)) {

                String keyPrefix = JAAS_CONFIG_PREFIX_PARAM + jaasClient + ".";

                if (index > -1) {
                    keyPrefix = keyPrefix + String.valueOf(index) + ".";
                }

                String keyParam = keyPrefix + JAAS_CONFIG_LOGIN_MODULE_NAME_PARAM;
                String loginModuleName = properties.getProperty(keyParam);

                if (loginModuleName == null) {
                    LOG.error("Unable to add JAAS configuration for client [{}] as it is missing param [{}]. Skipping JAAS config for [{}]", jaasClient, keyParam, jaasClient);
                    continue;
                } else {
                    loginModuleName = loginModuleName.trim();
                }

                keyParam = keyPrefix + JAAS_CONFIG_LOGIN_MODULE_CONTROL_FLAG_PARAM;
                String controlFlag = properties.getProperty(keyParam);

                AppConfigurationEntry.LoginModuleControlFlag loginControlFlag = null;
                if (controlFlag != null) {
                    controlFlag = controlFlag.trim().toLowerCase();
                    switch (controlFlag) {
                        case "optional":
                            loginControlFlag = AppConfigurationEntry.LoginModuleControlFlag.OPTIONAL;
                            break;
                        case "requisite":
                            loginControlFlag = AppConfigurationEntry.LoginModuleControlFlag.REQUISITE;
                            break;
                        case "sufficient":
                            loginControlFlag = AppConfigurationEntry.LoginModuleControlFlag.SUFFICIENT;
                            break;
                        case "required":
                            loginControlFlag = AppConfigurationEntry.LoginModuleControlFlag.REQUIRED;
                            break;
                        default:
                            String validValues = "optional|requisite|sufficient|required";
                            LOG.warn("Unknown JAAS configuration value for ({}) = [{}], valid value are [{}] using the default value, REQUIRED", keyParam, controlFlag, validValues);
                            loginControlFlag = AppConfigurationEntry.LoginModuleControlFlag.REQUIRED;
                            break;
                    }
                } else {
                    LOG.warn("Unable to find JAAS configuration ({}); using the default value, REQUIRED", keyParam);
                    loginControlFlag = AppConfigurationEntry.LoginModuleControlFlag.REQUIRED;
                }


                Map<String, String> options = new HashMap<>();
                String optionPrefix = keyPrefix + JAAS_CONFIG_LOGIN_OPTIONS_PREFIX + ".";
                int optionPrefixLen = optionPrefix.length();
                for (String key : properties.stringPropertyNames()) {
                    if (key.startsWith(optionPrefix)) {
                        String optionKey = key.substring(optionPrefixLen);
                        String optionVal = properties.getProperty(key);
                        if (optionVal != null) {
                            optionVal = optionVal.trim();

                            try {
                                if (optionKey.equalsIgnoreCase(JAAS_PRINCIPAL_PROP)) {
                                    optionVal = SecurityUtil.getServerPrincipal(optionVal, (String) null);
                                }
                            } catch (IOException e) {
                                LOG.warn("Failed to build serverPrincipal. Using provided value:[{}]", optionVal);
                            }
                        }
                        options.put(optionKey, optionVal);
                    }
                }

                AppConfigurationEntry entry = new AppConfigurationEntry(loginModuleName, loginControlFlag, options);

                if (LOG.isDebugEnabled()) {
                    StringBuilder sb = new StringBuilder();
                    sb.append("Adding client: [").append(jaasClient).append("{").append(index).append("}]\n");
                    sb.append("\tloginModule: [").append(loginModuleName).append("]\n");
                    sb.append("\tcontrolFlag: [").append(loginControlFlag).append("]\n");
                    for (String key : options.keySet()) {
                        String val = options.get(key);
                        sb.append("\tOptions:  [").append(key).append("] => [").append(val).append("]\n");
                    }
                    LOG.debug(sb.toString());
                }

                List<AppConfigurationEntry> retList = applicationConfigEntryMap.get(jaasClient);
                if (retList == null) {
                    retList = new ArrayList<>();
                    applicationConfigEntryMap.put(jaasClient, retList);
                }

                retList.add(entry);
            }
        }

        LOG.debug("<== InMemoryJAASConfiguration.initialize({})", applicationConfigEntryMap);
    }

    private static boolean isNumeric(String str) {
        return str.matches("-?\\d+(\\.\\d+)?");  //match a number with optional '-' and decimal.
    }

    public static void setConfigSectionRedirect(String name, String redirectTo) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("setConfigSectionRedirect({}, {})", name, redirectTo);
        }

        if (name != null) {
            if (redirectTo != null) {
                CONFIG_SECTION_REDIRECTS.put(name, redirectTo);
            } else {
                CONFIG_SECTION_REDIRECTS.remove(name);
            }
        }
    }

    private static String getConfigSectionRedirect(String name) {
        return name != null ? CONFIG_SECTION_REDIRECTS.get(name) : null;
    }
}
