/**
 * 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.server.web.rest;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.codec.binary.Base64;
import org.apache.kerby.has.common.HasConfig;
import org.apache.kerby.has.common.HasException;
import org.apache.kerby.has.common.util.HasUtil;
import org.apache.kerby.has.server.HasAuthenException;
import org.apache.kerby.has.server.HasServer;
import org.apache.kerby.has.server.HasServerPlugin;
import org.apache.kerby.has.server.HasServerPluginRegistry;
import org.apache.kerby.has.server.kdc.HasKdcHandler;
import org.apache.kerby.has.server.web.HostRoleType;
import org.apache.kerby.has.server.web.WebServer;
import org.apache.kerby.has.server.web.rest.param.AuthTokenParam;
import org.apache.kerby.has.server.web.rest.param.TypeParam;
import org.apache.hadoop.http.JettyUtils;
import org.apache.kerby.kerberos.kerb.KrbException;
import org.apache.kerby.kerberos.kerb.KrbRuntime;
import org.apache.kerby.kerberos.kerb.identity.backend.BackendConfig;
import org.apache.kerby.kerberos.kerb.provider.TokenDecoder;
import org.apache.kerby.kerberos.kerb.server.KdcUtil;
import org.apache.kerby.kerberos.kerb.type.base.AuthToken;
import org.apache.kerby.kerberos.kerb.type.base.KrbMessage;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.TreeMap;

/**
 * HAS web methods implementation.
 */
@Path("")
public class HasApi {

    @Context
    private ServletContext context;

    @Context
    private HttpServletRequest httpRequest;

    /**
     * Get krb5.conf file.
     *
     * @return Response
     */
    @GET
    @Path("/getkrb5conf")
    @Produces(MediaType.TEXT_PLAIN)
    public Response getKrb5Conf() {
        if (httpRequest.isSecure()) {
            final HasServer hasServer = WebServer.getHasServerFromContext(context);
            try {
                BackendConfig backendConfig = KdcUtil.getBackendConfig(hasServer.getConfDir());
                String backendJar = backendConfig.getString("kdc_identity_backend");
                File conf;
                if (backendJar.equals("org.apache.kerby.has.server.kdc.MySQLIdentityBackend")) {
                    conf = hasServer.generateKrb5Conf();
                } else {
                    File confDir = hasServer.getConfDir();
                    conf = new File(confDir, "krb5.conf");
                }
                return Response.ok(conf).header("Content-Disposition", "attachment; filename=krb5.conf").build();
            } catch (KrbException | HasException e) {
                throw new RuntimeException("Failed to get Krb5.conf. ", e);
            }
        }
        return Response.status(403).entity("HTTPS required.\n").build();
    }

    /**
     * Get has-client.conf file.
     *
     * @return Response
     */
    @GET
    @Path("/gethasconf")
    @Produces(MediaType.TEXT_PLAIN)
    public Response getHasConf() {
        if (httpRequest.isSecure()) {
            final HasServer hasServer = WebServer.getHasServerFromContext(context);
            try {
                BackendConfig backendConfig = KdcUtil.getBackendConfig(hasServer.getConfDir());
                String backendJar = backendConfig.getString("kdc_identity_backend");
                File conf;
                if (backendJar.equals("org.apache.kerby.has.server.kdc.MySQLIdentityBackend")) {
                    conf = hasServer.generateHasConf();
                } else {
                    File confDir = hasServer.getConfDir();
                    conf = new File(confDir, "has-server.conf");
                }
                return Response.ok(conf).header("Content-Disposition", "attachment; filename=has-client.conf").build();
            } catch (IOException | KrbException | HasException e) {
                throw new RuntimeException("Failed to get has-client.conf. ", e);
            }
        }
        return Response.status(403).entity("HTTPS required.\n").build();
    }

    /**
     * Get CA file.
     *
     * @return Response
     */
    @GET
    @Path("/getcert")
    @Produces(MediaType.TEXT_PLAIN)
    public Response getCert() {
        final HasServer hasServer = WebServer.getHasServerFromContext(context);
        String errMessage = null;
        File cert = null;
        try {
            HasConfig hasConfig = HasUtil.getHasConfig(
                new File(hasServer.getConfDir(), "has-server.conf"));
            if (hasConfig != null) {
                String certPath = hasConfig.getSslClientCert();
                cert = new File(certPath);
                if (!cert.exists()) {
                    errMessage = "Cert file not found in HAS server.";
                    WebServer.LOG.error("Cert file not found in HAS server.");
                }
            } else {
                errMessage = "has-server.conf not found.";
                WebServer.LOG.error("has-server.conf not found.");
            }
        } catch (HasException e) {
            errMessage = "Failed to get cert file" + e.getMessage();
            WebServer.LOG.error("Failed to get cert file" + e.getMessage());
        }
        if (errMessage == null) {
            return Response.ok(cert).header("Content-Disposition",
                "attachment;filename=" + cert.getName()).build();
        } else {
            return Response.status(Response.Status.NOT_FOUND).entity(errMessage).build();
        }
    }

    @GET
    @Path("/hostroles")
    @Produces(MediaType.APPLICATION_JSON + ";" + JettyUtils.UTF_8)
    public Response getRoles() {
        if (httpRequest.isSecure()) {
            JSONArray result = new JSONArray();
            try {
                for (HostRoleType role : HostRoleType.values()) {
                    JSONObject jso = new JSONObject();
                    jso.put("HostRole", role.getName());
                    JSONArray jsa = new JSONArray();
                    String[] princs = role.getPrincs();
                    for (String princ : princs) {
                        jsa.put(princ);
                    }
                    jso.put("PrincipalNames", jsa);
                    result.put(jso);
                }
                return Response.ok(result.toString() + "\n").type(MediaType.APPLICATION_JSON).build();
            } catch (Exception e) {
                WebServer.LOG.error("Failed to get host roles." + e.getMessage());
            }
            return Response.serverError().build();
        }
        return Response.status(403).entity("HTTPS required.\n").build();
    }

    @GET
    @Path("/kdcinit")
    @Produces(MediaType.TEXT_PLAIN)
    public Response kdcInit() {
        if (httpRequest.isSecure()) {
            final HasServer hasServer = WebServer.getHasServerFromContext(context);
            try {
                File adminKeytab = hasServer.initKdcServer();
                return Response.ok(adminKeytab).header("Content-Disposition",
                    "attachment; filename=" + adminKeytab.getName()).build();
            } catch (KrbException e) {
                System.err.println("[ERROR] " + e.getMessage());
            }
            return Response.serverError().build();
        }
        return Response.status(403).entity("HTTPS required.\n").build();
    }

    @GET
    @Path("/kdcstart")
    @Produces(MediaType.TEXT_PLAIN)
    public Response kdcStart() {
        if (httpRequest.isSecure()) {
            final HasServer hasServer = WebServer.getHasServerFromContext(context);
            JSONObject result = new JSONObject();
            String msg = "Succeed in starting KDC server.";

            try {
                hasServer.startKdcServer();
            } catch (HasException e) {
                WebServer.LOG.error("Fail to start kdc server. " + e.getMessage());
                msg = e.getMessage();
            }
            try {
                result.put("result", "success");
                result.put("msg", msg);
                return Response.ok(result.toString()).build();
            } catch (Exception e) {
                WebServer.LOG.error(e.getMessage());
                msg = e.getMessage();
            }
            try {
                result.put("result", "error");
                result.put("msg", msg);
            } catch (JSONException e) {
                WebServer.LOG.error(e.getMessage());
            }
            return Response.ok(result.toString()).build();
        }
        return Response.status(403).entity("HTTPS required.\n").build();
    }

    /**
     * Handle HTTP PUT request.
     */
    @PUT
    @Produces({MediaType.APPLICATION_OCTET_STREAM + "; " + JettyUtils.UTF_8,
        MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8})
    public Response asRequest(
        @QueryParam(TypeParam.NAME) @DefaultValue(TypeParam.DEFAULT)
        final TypeParam type,
        @QueryParam(AuthTokenParam.NAME) @DefaultValue(AuthTokenParam.DEFAULT)
        final AuthTokenParam authToken
    ) {
        return asRequest(type.getValue(), authToken.getValue());
    }

    private Response asRequest(String type, String tokenStr) {
        if (httpRequest.isSecure()) {
            final HasServer hasServer = WebServer.getHasServerFromContext(context);
            String errMessage = null;
            String js = null;
            ObjectMapper mapper = new ObjectMapper();
            final Map<String, Object> m = new TreeMap<String, Object>();

            if (hasServer.getKdcServer() == null) {
                errMessage = "Please start the has KDC server.";
            } else if (!tokenStr.isEmpty() && tokenStr != null) {
                HasKdcHandler kdcHandler = new HasKdcHandler(hasServer);

                TokenDecoder tokenDecoder = KrbRuntime.getTokenProvider("JWT").createTokenDecoder();

                AuthToken authToken = null;
                try {
                    authToken = tokenDecoder.decodeFromString(tokenStr);
                } catch (IOException e) {
                    errMessage = "Failed to decode the token string." + e.getMessage();
                    WebServer.LOG.error(errMessage);
                }
                HasServerPlugin tokenPlugin = null;
                try {
                    tokenPlugin = HasServerPluginRegistry.createPlugin(type);
                } catch (HasException e) {
                    errMessage = "Failed to get the plugin: " + type + ". " + e.getMessage();
                    WebServer.LOG.error(errMessage);
                }
                AuthToken verifiedAuthToken;
                try {
                    verifiedAuthToken = tokenPlugin.authenticate(authToken);
                } catch (HasAuthenException e) {
                    errMessage = "Failed to verify auth token. " + e.getMessage();
                    WebServer.LOG.error(errMessage);
                    verifiedAuthToken = null;
                }

                if (verifiedAuthToken != null) {
                    KrbMessage asRep = kdcHandler.getResponse(verifiedAuthToken,
                        (String) verifiedAuthToken.getAttributes().get("passPhrase"));

                    Base64 base64 = new Base64(0);
                    try {
                        m.put("type", tokenPlugin.getLoginType());
                        m.put("success", "true");
                        m.put("krbMessage", base64.encodeToString(asRep.encode()));
                    } catch (IOException e) {
                        errMessage = "Failed to encode KrbMessage." + e.getMessage();
                        WebServer.LOG.error(errMessage);
                    }

                }
            } else {
                errMessage = "The token string should not be empty.";
                WebServer.LOG.error(errMessage);
            }

            if (errMessage != null) {
                m.put("success", "false");
                m.put("krbMessage", errMessage);
            }
            try {
                js = mapper.writeValueAsString(m);
            } catch (JsonProcessingException e) {
                WebServer.LOG.error("Failed write values to string." + e.getMessage());
            }
            return Response.ok(js).type(MediaType.APPLICATION_JSON).build();
        }
        return Response.status(403).entity("HTTPS required.\n").build();
    }
}
