/**
 * 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 org.apache.kerby.has.server.HasServer;
import org.apache.kerby.has.server.web.WebServer;
import org.apache.kerby.has.server.web.rest.param.PasswordParam;
import org.apache.kerby.has.server.web.rest.param.PrincipalParam;
import org.apache.kerby.kerberos.kerb.KrbException;
import org.apache.kerby.kerberos.kerb.admin.kadmin.local.LocalKadminImpl;
import org.apache.kerby.kerberos.kerb.server.KdcSetting;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONObject;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
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.util.List;

/**
 * Kadmin web methods implementation.
 */
public class KadminApi {
    @Context
    private ServletContext context;

    @Context
    private HttpServletRequest httpRequest;

        /**
     * export single keytab file
     *
     * @param principal principal name to export keytab file
     * @return Response
     */
    @GET
    @Path("/exportkeytab")
    @Produces(MediaType.TEXT_PLAIN)
    public Response exportKeytab(@QueryParam("principal") final String principal) {
        if (httpRequest.isSecure()) {
            WebServer.LOG.info("Exporting keytab file for " + principal + "...");
            String msg;
            LocalKadminImpl localKadmin;
            HasServer hasServer = WebServer.getHasServerFromContext(context);
            KdcSetting serverSetting = hasServer.getKdcServer().getKdcSetting();
            try {
                localKadmin = new LocalKadminImpl(serverSetting);
            } catch (KrbException e) {
                msg = "Failed to create local kadmin." + e.getMessage();
                WebServer.LOG.info(msg);
                return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
            }
            WebServer.LOG.info("Create keytab file for " + principal + " successfully.");
            if (principal != null) {
                File path = new File("/tmp/" + System.currentTimeMillis());
                if (path.mkdirs()) {
                    File keytabFile = new File(path, principal + ".keytab");
                    try {
                        localKadmin.exportKeytab(keytabFile, principal);
                        return Response.ok(keytabFile).header("Content-Disposition", "attachment; filename="
                            + keytabFile.getName()).build();
                    } catch (KrbException e) {
                        msg = "Failed to export keytab. " + e.toString();
                        WebServer.LOG.error(msg);
                        return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
                    }
                }
            }
            return Response.serverError().build();
        }
        return Response.status(Response.Status.FORBIDDEN).entity("HTTPS required.\n").build();
    }

    @GET
    @Path("/getprincipals")
    @Produces(MediaType.APPLICATION_JSON)
    public Response getprincipals(@QueryParam("exp") String exp) {
        if (httpRequest.isSecure()) {
            WebServer.LOG.info("Request to get principals.");
            JSONObject result = new JSONObject();
            String msg;
            LocalKadminImpl localKadmin;
            HasServer hasServer = WebServer.getHasServerFromContext(context);
            KdcSetting serverSetting = hasServer.getKdcServer().getKdcSetting();
            try {
                localKadmin = new LocalKadminImpl(serverSetting);
            } catch (KrbException e) {
                msg = "Failed to create local kadmin." + e.getMessage();
                WebServer.LOG.info(msg);
                return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
            }
            try {
                JSONArray principals = new JSONArray();
                List<String> princList = localKadmin.getPrincipals(exp);
                for (String princ : princList) {
                    principals.put(princ);
                }
                WebServer.LOG.info("Success to get principals with JSON.");
                result.put("result", "success");
                result.put("msg", principals.toString());
                return Response.ok(result.toString()).build();
            } catch (Exception e) {
                msg = "Failed to get principals,because : " + e.getMessage();
                WebServer.LOG.error(msg);
                return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
            }
        }
        return Response.status(Response.Status.FORBIDDEN).entity("HTTPS required.\n").build();
    }

    /**
     * Add principal by name and password.
     *
     * @param principal principal name.
     * @param password  principal password
     * @return Response
     */
    @POST
    @Path("/addprincipal")
    @Produces(MediaType.TEXT_PLAIN)
    public Response addprincipal(@QueryParam(PrincipalParam.NAME) @DefaultValue(PrincipalParam.DEFAULT)
                                 final PrincipalParam principal,
                                 @QueryParam(PasswordParam.NAME) @DefaultValue(PasswordParam.DEFAULT)
                                 final PasswordParam password) {
        if (httpRequest.isSecure()) {
            WebServer.LOG.info("Request to add the principal named " + principal.getValue());
            String msg;
            LocalKadminImpl localKadmin;
            HasServer hasServer = WebServer.getHasServerFromContext(context);
            KdcSetting serverSetting = hasServer.getKdcServer().getKdcSetting();
            try {
                localKadmin = new LocalKadminImpl(serverSetting);
            } catch (KrbException e) {
                msg = "Failed to create local kadmin." + e.getMessage();
                WebServer.LOG.info(msg);
                return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
            }
            JSONObject result = new JSONObject();
            try {
                localKadmin.addPrincipal(principal.getValue(), password.getValue());
                msg = "Add principal successfully.";
                result.put("result", "success");
                result.put("msg", msg);
                return Response.ok(result.toString()).build();
            } catch (Exception e) {
                msg = "Failed to add " + principal + " principal, because: " + e.getMessage();
                WebServer.LOG.error(msg);
                return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
            }
        }
        return Response.status(Response.Status.FORBIDDEN).entity("HTTPS required.\n").build();
    }

    @POST
    @Path("/renameprincipal")
    @Produces(MediaType.TEXT_PLAIN)
    public Response renamePrincipal(@QueryParam("oldprincipal") String oldPrincipal,
                                    @QueryParam("newprincipal") String newPrincipal) {
        if (httpRequest.isSecure()) {
            WebServer.LOG.info("Request to rename " + oldPrincipal + " to " + newPrincipal);
            JSONObject result = new JSONObject();
            String msg;
            if (oldPrincipal != null && newPrincipal != null) {
                LocalKadminImpl localKadmin;
                HasServer hasServer = WebServer.getHasServerFromContext(context);
                KdcSetting serverSetting = hasServer.getKdcServer().getKdcSetting();
                try {
                    localKadmin = new LocalKadminImpl(serverSetting);
                } catch (KrbException e) {
                    msg = "Failed to create local kadmin." + e.getMessage();
                    WebServer.LOG.info(msg);
                    return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
                }

                try {
                    localKadmin.renamePrincipal(oldPrincipal, newPrincipal);
                    msg = "Rename principal successfully.";
                    result.put("result", "success");
                    result.put("msg", msg);
                    return Response.ok(result.toString()).build();
                } catch (Exception e) {
                    msg = "Failed to rename principal " + oldPrincipal + " to "
                        + newPrincipal + ",because: " + e.getMessage();
                    WebServer.LOG.error(msg);
                    return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
                }
            } else {
                msg = "Value of old or new principal is null.";
                WebServer.LOG.error(msg);
                return Response.status(Response.Status.NOT_FOUND).entity(msg).build();
            }
        }
        return Response.status(Response.Status.FORBIDDEN).entity("HTTPS required.\n").build();
    }

    /**
     * Delete principal by name.
     *
     * @param principal principal like "admin" or "admin@HADOOP.COM".
     * @return Response
     */
    @DELETE
    @Path("/deleteprincipal")
    @Produces(MediaType.TEXT_PLAIN)
    public Response deleteprincipal(@QueryParam(PrincipalParam.NAME) @DefaultValue(PrincipalParam.DEFAULT)
                                    final PrincipalParam principal) {
        if (httpRequest.isSecure()) {
            WebServer.LOG.info("Request to delete the principal named " + principal.getValue());
            JSONObject result = new JSONObject();
            String msg;
            LocalKadminImpl localKadmin;
            HasServer hasServer = WebServer.getHasServerFromContext(context);
            KdcSetting serverSetting = hasServer.getKdcServer().getKdcSetting();
            try {
                localKadmin = new LocalKadminImpl(serverSetting);
            } catch (KrbException e) {
                msg = "Failed to create local kadmin." + e.getMessage();
                WebServer.LOG.info(msg);
                return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
            }

            try {
                localKadmin.deletePrincipal(principal.getValue());
                msg = "Delete principal successfully.";
                result.put("result", "success");
                result.put("msg", msg);
                return Response.ok(result.toString()).build();
            } catch (Exception e) {
                msg = "Failed to delete the principal named " + principal.getValue()
                    + ",because : " + e.getMessage();
                WebServer.LOG.error(msg);
                return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
            }
        }
        return Response.status(403).entity("HTTPS required.\n").build();
    }
}
