/**
 * 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
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * 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.kerby.has.client;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.text.CharacterPredicates;
import org.apache.commons.text.RandomStringGenerator;
import org.apache.kerby.has.common.HasConfig;
import org.apache.kerby.has.common.HasConfigKey;
import org.apache.kerby.has.common.HasException;
import org.apache.kerby.has.common.ssl.SSLFactory;
import org.apache.kerby.has.common.util.HasUtil;
import org.apache.kerby.has.common.util.URLConnectionFactory;
import org.apache.kerby.kerberos.kerb.KrbCodec;
import org.apache.kerby.kerberos.kerb.KrbException;
import org.apache.kerby.kerberos.kerb.KrbRuntime;
import org.apache.kerby.kerberos.kerb.ccache.CredentialCache;
import org.apache.kerby.kerberos.kerb.crypto.EncryptionHandler;
import org.apache.kerby.kerberos.kerb.provider.TokenEncoder;
import org.apache.kerby.kerberos.kerb.type.base.AuthToken;
import org.apache.kerby.kerberos.kerb.type.base.EncryptedData;
import org.apache.kerby.kerberos.kerb.type.base.EncryptionKey;
import org.apache.kerby.kerberos.kerb.type.base.KeyUsage;
import org.apache.kerby.kerberos.kerb.type.base.KrbError;
import org.apache.kerby.kerberos.kerb.type.base.KrbMessage;
import org.apache.kerby.kerberos.kerb.type.base.KrbMessageType;
import org.apache.kerby.kerberos.kerb.type.base.PrincipalName;
import org.apache.kerby.kerberos.kerb.type.kdc.EncAsRepPart;
import org.apache.kerby.kerberos.kerb.type.kdc.EncKdcRepPart;
import org.apache.kerby.kerberos.kerb.type.kdc.KdcRep;
import org.apache.kerby.kerberos.kerb.type.ticket.TgtTicket;
import org.apache.kerby.util.IOUtil;
import org.apache.kerby.util.SysUtil;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.ByteBuffer;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.PublicKey;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Date;

/**
 * HAS client
 */
public class HasClient {

    public static final Logger LOG = LoggerFactory.getLogger(HasClient.class);

    public static final String JAVA_SECURITY_KRB5_CONF = "java.security.krb5.conf";
    public static final String HAS_HTTP_PORT_DEFAULT = "9870";
    public static final String HAS_CONFIG_DEFAULT = "/etc/has/has-client.conf";
    public static final String CA_ROOT_DEFAULT = "/etc/has/ca-root.pem";

    private String hadoopSecurityHas = null;
    private String type;
    private File clientConfigFolder;


    public HasClient() { }

    /**
     * Create an instance of the HasClient.
     *
     * @param hadoopSecurityHas the has config
     */
    public HasClient(String hadoopSecurityHas) {
        this.hadoopSecurityHas = hadoopSecurityHas;
    }


    public TgtTicket requestTgt() throws HasException {
        HasConfig config;
        if (hadoopSecurityHas == null) {
            String hasClientConf = System.getenv("HAS_CLIENT_CONF");
            if (hasClientConf == null) {
                hasClientConf = HAS_CONFIG_DEFAULT;
            }
            LOG.debug("has-client conf path: " + hasClientConf);
            File confFile = new File(hasClientConf);
            if (!confFile.exists()) {
                throw new HasException("The HAS client config file: " + hasClientConf
                    + " does not exist.");
            }
            try {
                config = HasUtil.getHasConfig(confFile);
            } catch (HasException e) {
                LOG.error("Failed to get has client config: " + e.getMessage());
                throw new HasException("Failed to get has client config: " + e.getMessage());
            }
        } else {
            config = new HasConfig();
            String[] urls = hadoopSecurityHas.split(";");
            StringBuilder host = new StringBuilder();
            int port = 0;
            try {
                for (String url : urls) {
                    URI uri = new URI(url.trim());

                    // parse host
                    host.append(uri.getHost()).append(",");

                    // parse port
                    if (port == 0) {
                        port = uri.getPort();
                    } else {
                        if (port != uri.getPort()) {
                            throw new HasException("Invalid port: not even.");
                        }
                    }

                    // We will get the auth type from env first
                    type = System.getenv("auth_type");
                    // parse host
                    if (type == null) {
                        String[] strs = uri.getQuery().split("=");
                        if (strs[0].equals("auth_type")) {
                            type = strs[1];
                        } else {
                            LOG.warn("No auth type in conf.");
                        }
                    }
                }
                if (host.length() == 0 || port == 0) {
                    throw new HasException("host is null.");
                } else {
                    config.setString(HasConfigKey.HTTPS_HOST,  host.subSequence(0, host.length() - 1).toString());
                    config.setInt(HasConfigKey.HTTPS_PORT, port);
                    config.setString(HasConfigKey.AUTH_TYPE, type);
                }
            } catch (URISyntaxException e) {
                LOG.error("Errors occurred when getting web url. " + e.getMessage());
                throw new HasException(
                    "Errors occurred when getting web url. " + e.getMessage());
            }
        }
        if (config == null) {
            throw new HasException("Failed to get HAS client config.");
        }
        clientConfigFolder = new File("/etc/has/" + config.getHttpsHost());
        if (!clientConfigFolder.exists()) {
            clientConfigFolder.mkdirs();
        }

        // get and set ssl-client/trustStore first
        String sslClientConfPath = clientConfigFolder + "/ssl-client.conf";
        loadSslClientConf(config, sslClientConfPath);
        config.setString(HasConfigKey.SSL_CLIENT_CONF, sslClientConfPath);

        HasClientPlugin plugin;
        try {
            plugin = getClientTokenPlugin(config);
        } catch (HasException e) {
            LOG.error("Failed to get client token plugin from config: " + e.getMessage());
            throw new HasException(
                "Failed to get client token plugin from config: " + e.getMessage());
        }
        AuthToken authToken;
        try {
            authToken = plugin.login(config);
        } catch (HasLoginException e) {
            LOG.error("Plugin login failed: " + e.getMessage());
            throw new HasException(
                "Plugin login failed: " + e.getMessage());
        }
        type = plugin.getLoginType();

        LOG.debug("The plugin type is: " + type);

        return requestTgt(authToken, type, config);
    }

    private HasClientPlugin getClientTokenPlugin(HasConfig config) throws HasException {
        String pluginName = config.getPluginName();
        HasClientPlugin clientPlugin;
        if (pluginName != null) {
            clientPlugin = HasClientPluginRegistry.createPlugin(pluginName);
        } else {
            throw new HasException("Please set the plugin name in has client conf");
        }

        return clientPlugin;
    }

    /**
     * Request a TGT with user token, plugin type and has config.
     * @param authToken
     * @param type
     * @param config
     * @return TGT
     * @throws HasException e
     */
    public TgtTicket requestTgt(AuthToken authToken, String type, HasConfig config)
        throws HasException {
        TokenEncoder tokenEncoder = KrbRuntime.getTokenProvider("JWT").createTokenEncoder();

        String tokenString;
        try {
            tokenString = tokenEncoder.encodeAsString(authToken);
        } catch (KrbException e) {
            LOG.debug("Failed to decode the auth token.");
            throw new HasException("Failed to decode the auth token." + e.getMessage());
        }

        JSONObject json = null;
        int responseStatus = 0;
        boolean success = false;
        if (config.getHttpsPort() != null && config.getHttpsHost() != null) {
            String sslClientConfPath = clientConfigFolder + "/ssl-client.conf";
            config.setString(SSLFactory.SSL_HOSTNAME_VERIFIER_KEY, "ALLOW_ALL");
            config.setString(SSLFactory.SSL_CLIENT_CONF_KEY, sslClientConfPath);
            config.setBoolean(SSLFactory.SSL_REQUIRE_CLIENT_CERT_KEY, false);

            URLConnectionFactory connectionFactory = URLConnectionFactory
                .newDefaultURLConnectionFactory(config);

            URL url;
            String[] hosts = config.getHttpsHost().split(",");
            for (String host : hosts) {
                try {
                    url = new URL("https://" + host.trim() + ":" + config.getHttpsPort()
                        + "/has/v1?type=" + type + "&authToken=" + tokenString);
                } catch (MalformedURLException e) {
                    LOG.warn("Failed to get url. " + e.toString());
                    continue;
                }
                HttpURLConnection conn;
                try {
                    conn = (HttpURLConnection) connectionFactory.openConnection(url);
                } catch (IOException e) {
                    LOG.warn("Failed to open connection. " + e.toString());
                    continue;
                }

                conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
                try {
                    conn.setRequestMethod("PUT");
                } catch (ProtocolException e) {
                    LOG.warn("Failed to set request method. " + e.toString());
                    continue;
                }
                conn.setDoOutput(true);
                conn.setDoInput(true);

                try {
                    conn.connect();

                    responseStatus = conn.getResponseCode();
                    switch (responseStatus) {
                        case 200:
                        case 201:
                            BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                            StringBuilder sb = new StringBuilder();
                            String line;
                            while ((line = br.readLine()) != null) {
                                sb.append(line + "\n");
                            }
                            br.close();

                            json = new JSONObject(sb.toString());
                    }

                } catch (IOException | JSONException e) {
                    LOG.warn("ERROR! " + e.toString());
                    continue;
                }

                if (responseStatus == 200 || responseStatus == 201) {
                    success = true;
                    break;
                }
            }
            if (!success) {
                throw new HasException("Failed : HTTP error code : "
                    + responseStatus);
            }
        } else {
            throw new HasException("Please set https host and port.");
        }

        LOG.debug("Return from Server .... \n");

        try {
            return handleResponse(json, (String) authToken.getAttributes().get("passPhrase"));
        } catch (HasException e) {
            LOG.debug("Failed to handle response when requesting tgt ticket in client."
                + e.getMessage());
            throw new HasException(e);
        }
    }

    private File loadSslClientConf(HasConfig config, String sslClientConfPath) throws HasException {
        File sslClientConf = new File(sslClientConfPath);
        if (!sslClientConf.exists()) {
            String httpHost = config.getHttpHost();
            String httpPort = config.getHttpPort();
            if (httpHost == null) {
                LOG.warn("Can't find the http host in config, the https host will be used.");
                httpHost = config.getHttpsHost();
            }
            if (httpPort == null) {
                LOG.warn("Can't find the http port in config, the default http port will be used.");
                httpPort = HAS_HTTP_PORT_DEFAULT;
            }
            X509Certificate certificate = getCertificate(httpHost, httpPort);
            if (verifyCertificate(certificate)) {
                String password = createTrustStore(config.getHttpsHost(), certificate);
                createClientSSLConfig(password);
            } else {
                throw new HasException("The certificate from HAS server is invalid.");
            }
        }
        return sslClientConf;
    }

    public KrbMessage getKrbMessage(JSONObject json) throws HasException {

        LOG.debug("Starting to get the message from has server.");

        try {
            boolean success = json.getBoolean("success");
            if (!success) {
                throw new HasException(json.getString("krbMessage"));
            }
        } catch (JSONException e) {
            LOG.debug("Failed to get message." + e);
            throw new HasException("Failed to get message." + e);
        }

        String typeString;
        try {
            typeString = json.getString("type");
        } catch (JSONException e) {
            LOG.debug("Failed to get message." + e);
            throw new HasException("Failed to get message." + e);
        }

        if (typeString != null && typeString.equals(type)) {
            LOG.debug("The message type is " + type);
            String krbMessageString = null;
            try {
                krbMessageString = json.getString("krbMessage");
            } catch (JSONException e) {
                LOG.debug("Failed to get the krbMessage. " + e);
            }
            Base64 base64 = new Base64(0);
            byte[] krbMessage = base64.decode(krbMessageString);
            ByteBuffer byteBuffer = ByteBuffer.wrap(krbMessage);
            KrbMessage kdcRep;
            try {
                kdcRep = KrbCodec.decodeMessage(byteBuffer);
            } catch (IOException e) {
                throw new HasException("Krb decoding message failed", e);
            }
            return kdcRep;
        } else {
            throw new HasException("Can't get the right message from server.");
        }
    }

    public TgtTicket handleResponse(JSONObject json, String passPhrase)
        throws HasException {
        KrbMessage kdcRep = getKrbMessage(json);

        KrbMessageType messageType = kdcRep.getMsgType();
        if (messageType == KrbMessageType.AS_REP) {
            return processResponse((KdcRep) kdcRep, passPhrase);
        } else if (messageType == KrbMessageType.KRB_ERROR) {
            KrbError error = (KrbError) kdcRep;
            LOG.error("HAS server response with message: "
                + error.getErrorCode().getMessage());

            throw new HasException(error.getEtext());
        }
        return null;
    }

    public TgtTicket processResponse(KdcRep kdcRep, String passPhrase)
        throws HasException {

        PrincipalName clientPrincipal = kdcRep.getCname();
        String clientRealm = kdcRep.getCrealm();
        clientPrincipal.setRealm(clientRealm);

        // Get the client to decrypt the EncryptedData
        EncryptionKey clientKey = null;
        try {
            clientKey = HasUtil.getClientKey(clientPrincipal.getName(),
                passPhrase,
                kdcRep.getEncryptedEncPart().getEType());
        } catch (KrbException e) {
            throw new HasException("Could not generate key. " + e.getMessage());
        }

        byte[] decryptedData = decryptWithClientKey(kdcRep.getEncryptedEncPart(),
            KeyUsage.AS_REP_ENCPART, clientKey);
        if ((decryptedData[0] & 0x1f) == 26) {
            decryptedData[0] = (byte) (decryptedData[0] - 1);
        }
        EncKdcRepPart encKdcRepPart = new EncAsRepPart();
        try {
            encKdcRepPart.decode(decryptedData);
        } catch (IOException e) {
            throw new HasException("Failed to decode EncAsRepPart", e);
        }
        kdcRep.setEncPart(encKdcRepPart);

        TgtTicket tgtTicket = getTicket(kdcRep);
        LOG.debug("Ticket expire time: " + tgtTicket.getEncKdcRepPart().getEndTime());

        storeTgtTicket(tgtTicket);

        return tgtTicket;

    }

    private void storeTgtTicket(TgtTicket tgtTicket) throws HasException {
        String ccacheName = getCcacheName();
        File ccacheFile = new File(ccacheName);
        LOG.info("Storing the tgt to the credential cache file.");
        if (!ccacheFile.exists()) {
            createCacheFile(ccacheFile);
        }
        if (ccacheFile.exists() && ccacheFile.canWrite()) {
            CredentialCache cCache = new CredentialCache(tgtTicket);
            try {
                cCache.store(ccacheFile);
            } catch (IOException e) {
                throw new HasException("Failed to store tgt", e);
            }
        } else {
            throw new IllegalArgumentException("Invalid ccache file, "
                    + "not exist or writable: " + ccacheFile.getAbsolutePath());
        }
    }

    /**
     * Create the specified credential cache file.
     */
    private void createCacheFile(File ccacheFile) throws HasException {
        try {
            if (!ccacheFile.createNewFile()) {
                throw new HasException("Failed to create ccache file "
                        + ccacheFile.getAbsolutePath());
            }
            // sets read-write permissions to owner only
            ccacheFile.setReadable(true, true);
            if (!ccacheFile.setWritable(true, true)) {
                throw new HasException("Cache file is not readable.");
            }
        } catch (IOException e) {
            throw new HasException("Failed to create ccache file "
                    + ccacheFile.getAbsolutePath(), e);
        }
    }

    /**
     * Get credential cache file name.
     */
    private String getCcacheName() {
        final String ccacheNameEnv = System.getenv("KRB5CCNAME");
        String ccacheName;
        if (ccacheNameEnv != null) {
            ccacheName = ccacheNameEnv;
        } else {
            StringBuilder uid = new StringBuilder();
            try {
                //Get UID through "id -u" command
                String command = "id -u";
                Process child = Runtime.getRuntime().exec(command);
                InputStream in = child.getInputStream();
                int c;
                while ((c = in.read()) != -1) {
                    uid.append((char) c);
                }
                in.close();
            } catch (IOException e) {
                System.err.println("Failed to get UID.");
                System.exit(1);
            }
            ccacheName = "krb5cc_" + uid.toString().trim();
            ccacheName = SysUtil.getTempDir().toString() + "/" + ccacheName;
        }

        return ccacheName;
    }

    protected byte[] decryptWithClientKey(EncryptedData data,
                                          KeyUsage usage,
                                          EncryptionKey clientKey) throws HasException {
        if (clientKey == null) {
            throw new HasException("Client key isn't available");
        }
        try {
            return EncryptionHandler.decrypt(data, clientKey, usage);
        } catch (KrbException e) {
            throw new HasException("Errors occurred when decrypting the data." + e.getMessage());
        }
    }

    /**
     * Get the tgt ticket from KdcRep
     *
     * @param kdcRep
     */
    public TgtTicket getTicket(KdcRep kdcRep) {
        TgtTicket tgtTicket = new TgtTicket(kdcRep.getTicket(),
            (EncAsRepPart) kdcRep.getEncPart(), kdcRep.getCname());
        return tgtTicket;
    }

    /**
     * Get certificate from HAS server.
     *
     */
    private X509Certificate getCertificate(String host, String port) throws HasException {
        X509Certificate certificate;

        HttpURLConnection httpConn = null;

        URL url;
        try {
            url = new URL("http://" + host + ":" + port + "/has/v1/getcert");
        } catch (MalformedURLException e) {
            throw new HasException("Failed to create a URL object.", e);
        }
        try {
            httpConn = (HttpURLConnection) url.openConnection();
        } catch (IOException e) {
            e.printStackTrace();
        }
        httpConn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
        try {
            httpConn.setRequestMethod("GET");
        } catch (ProtocolException e) {
            LOG.error("Fail to add principal. " + e);
            throw new HasException("Failed to set the method for URL request.", e);
        }

        try {
            httpConn.connect();
            if (httpConn.getResponseCode() != 200) {
                throw new HasException(HasClientUtil.getResponse(httpConn));
            }
            try {
                CertificateFactory factory = CertificateFactory.getInstance("X.509");
                InputStream in = HasClientUtil.getInputStream(httpConn);
                certificate = (X509Certificate) factory.generateCertificate(in);
            } catch (CertificateException e) {
                throw new HasException("Failed to get certificate from HAS server", e);
            }

        } catch (IOException e) {
            throw new HasException("IO error occurred.", e);
        }

        return certificate;
    }

    /**
     * Verify certificate.
     */
    private boolean verifyCertificate(X509Certificate certificate) throws HasException {
        // Check if certificate is expired
        try {
            Date date = new Date();
            certificate.checkValidity(date);
        } catch (GeneralSecurityException e) {
            return false;
        }

        // Get certificate from ca root
        X509Certificate caRoot;
        try {
            //Get the ca root path from env, client should export it.
            String caRootPath = System.getenv("CA_ROOT");
            if (caRootPath == null) {
                caRootPath = CA_ROOT_DEFAULT;
            }
            File caRootFile;
            if (caRootPath != null) {
                caRootFile = new File(caRootPath);
                if (!caRootFile.exists()) {
                    throw new HasException("CA_ROOT: " + caRootPath + " not exist.");
                }
            } else {
                throw new HasException("Please set the CA_ROOT.");
            }

            CertificateFactory factory = CertificateFactory.getInstance("X.509");
            try (FileInputStream in = new FileInputStream(caRootFile)) {
                caRoot = (X509Certificate) factory.generateCertificate(in);
            }
        } catch (CertificateException | IOException e) {
            throw new HasException("Failed to get certificate from ca root file", e);
        }

        // Verify certificate with root certificate
        try {
            PublicKey publicKey = caRoot.getPublicKey();
            certificate.verify(publicKey);
        } catch (GeneralSecurityException e) {
            return false;
        }

        return true;
    }

    /**
     * Create and save truststore file based on certificate.
     *
     */
    private String createTrustStore(String host, X509Certificate certificate) throws HasException {
        KeyStore trustStore;

        // Create password
        RandomStringGenerator generator = new RandomStringGenerator.Builder()
            .withinRange('a', 'z')
            .filteredBy(CharacterPredicates.LETTERS, CharacterPredicates.DIGITS)
            .build();
        String password = generator.generate(15);

        File trustStoreFile = new File(clientConfigFolder + "/truststore.jks");
        try {
            trustStore = KeyStore.getInstance("jks");
            trustStore.load(null, null);
            trustStore.setCertificateEntry(host, certificate);
            FileOutputStream out = new FileOutputStream(trustStoreFile);
            trustStore.store(out, password.toCharArray());
            out.close();
        } catch (IOException | GeneralSecurityException e) {
            throw new HasException("Failed to create and save truststore file", e);
        }
        return password;
    }

    /**
     * Create ssl configuration file for client.
     *
     */
    private void createClientSSLConfig(String password) throws HasException {
        String resourcePath = "/ssl-client.conf.template";
        InputStream templateResource = getClass().getResourceAsStream(resourcePath);
        try {
            String content = IOUtil.readInput(templateResource);
            content = content.replaceAll("_location_", clientConfigFolder.getAbsolutePath()
                + "/truststore.jks");
            content = content.replaceAll("_password_", password);

            IOUtil.writeFile(content, new File(clientConfigFolder + "/ssl-client.conf"));
        } catch (IOException e) {
            throw new HasException("Failed to create client ssl configuration file", e);
        }
    }
}
