/*
 * 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.knox.gateway.service.metadata;

import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
import static javax.ws.rs.core.MediaType.APPLICATION_OCTET_STREAM;
import static javax.ws.rs.core.MediaType.APPLICATION_XML;

import java.io.IOException;
import java.nio.file.Paths;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Locale;
import java.util.Optional;
import java.util.Set;
import java.util.TreeSet;

import javax.inject.Singleton;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.Response.Status;

import org.apache.knox.gateway.config.GatewayConfig;
import org.apache.knox.gateway.i18n.messages.MessagesFactory;
import org.apache.knox.gateway.service.definition.Metadata;
import org.apache.knox.gateway.service.definition.ServiceDefinitionPair;
import org.apache.knox.gateway.services.GatewayServices;
import org.apache.knox.gateway.services.ServerInfoService;
import org.apache.knox.gateway.services.ServiceType;
import org.apache.knox.gateway.services.registry.ServiceDefinitionRegistry;
import org.apache.knox.gateway.services.security.KeystoreService;
import org.apache.knox.gateway.services.security.KeystoreServiceException;
import org.apache.knox.gateway.services.topology.TopologyService;
import org.apache.knox.gateway.topology.Service;
import org.apache.knox.gateway.topology.Topology;
import org.apache.knox.gateway.util.X509CertificateUtil;

@Singleton
@Path("/api/v1/metadata")
public class KnoxMetadataResource {
  private static final MetadataServiceMessages LOG = MessagesFactory.get(MetadataServiceMessages.class);
  private static final String SNAPSHOT_VERSION_POSTFIX = "-SNAPSHOT";
  private static final Set<String> UNREAL_SERVICES = Collections.unmodifiableSet(new HashSet<>(Arrays.asList("NAMENODE", "JOBTRACKER")));

  private Set<String> pinnedTopologies;
  private java.nio.file.Path pemFilePath;
  private java.nio.file.Path jksFilePath;

  @Context
  private HttpServletRequest request;

  @GET
  @Produces({ APPLICATION_JSON, APPLICATION_XML })
  @Path("info")
  public GeneralProxyInformation getGeneralProxyInformation() {
    final GeneralProxyInformation proxyInfo = new GeneralProxyInformation();
    final GatewayServices gatewayServices = (GatewayServices) request.getServletContext().getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
    if (gatewayServices != null) {
      final ServerInfoService serviceInfoService = gatewayServices.getService(ServiceType.SERVER_INFO_SERVICE);
      final String versionInfo = serviceInfoService.getBuildVersion() + " (hash=" + serviceInfoService.getBuildHash() + ")";
      proxyInfo.setVersion(versionInfo);
      proxyInfo.setAdminApiBookUrl(
          String.format(Locale.ROOT, "https://knox.apache.org/books/knox-%s/user-guide.html#Admin+API", getAdminApiBookVersion(serviceInfoService.getBuildVersion())));
      final GatewayConfig config = (GatewayConfig) request.getServletContext().getAttribute(GatewayConfig.GATEWAY_CONFIG_ATTRIBUTE);
      proxyInfo.setAdminUiUrl(getBaseGatewayUrl(config) + "/manager/admin-ui/");
    }

    return proxyInfo;
  }

  private String getAdminApiBookVersion(String buildVersion) {
    return buildVersion.replaceAll(SNAPSHOT_VERSION_POSTFIX, "").replaceAll("\\.", "-");
  }

  @GET
  @Produces(APPLICATION_OCTET_STREAM)
  @Path("publicCert")
  public Response getPublicCertification(@QueryParam("type") @DefaultValue("pem") String certType) {
    final GatewayServices gatewayServices = (GatewayServices) request.getServletContext().getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
    if (gatewayServices != null) {
      final GatewayConfig config = (GatewayConfig) request.getServletContext().getAttribute(GatewayConfig.GATEWAY_CONFIG_ATTRIBUTE);
      final Certificate certificate = getPublicCertificate(gatewayServices, config);
      if (certificate != null) {
        if ("pem".equals(certType)) {
          generateCertificatePem(certificate, config);
          return generateSuccessFileDownloadResponse(pemFilePath);
        } else if ("jks".equals(certType)) {
          generateCertificateJks(certificate, config);
          return generateSuccessFileDownloadResponse(jksFilePath);
        } else {
          return generateFailureFileDownloadResponse(Status.BAD_REQUEST, "Invalid certification type provided!");
        }
      }
    }
    return generateFailureFileDownloadResponse(Status.SERVICE_UNAVAILABLE, "Could not generate public certificate");
  }

  private Response generateSuccessFileDownloadResponse(java.nio.file.Path publicCertFilePath) {
    final ResponseBuilder responseBuilder = Response.ok(publicCertFilePath.toFile());
    responseBuilder.header("Content-Disposition", "attachment;filename=" + publicCertFilePath.getFileName().toString());
    return responseBuilder.build();
  }

  private Response generateFailureFileDownloadResponse(Status status, String errorMessage) {
    final ResponseBuilder responseBuilder = Response.status(status);
    responseBuilder.entity(errorMessage);
    return responseBuilder.build();
  }

  private Certificate getPublicCertificate(GatewayServices gatewayServices, GatewayConfig config) {
    try {
      final KeystoreService keystoreService = gatewayServices.getService(ServiceType.KEYSTORE_SERVICE);
      return keystoreService.getKeystoreForGateway().getCertificate(config.getIdentityKeyAlias());
    } catch (KeyStoreException | KeystoreServiceException e) {
      LOG.failedToFetchPublicCert(e.getMessage(), e);
      return null;
    }
  }

  private void generateCertificatePem(Certificate certificate, GatewayConfig gatewayConfig) {
    try {
      if (pemFilePath == null || !pemFilePath.toFile().exists()) {
        pemFilePath = Paths.get(gatewayConfig.getGatewaySecurityDir(), "gateway-client-trust.pem");
        X509CertificateUtil.writeCertificateToFile(certificate, pemFilePath.toFile());
      }
    } catch (CertificateEncodingException | IOException e) {
      LOG.failedToGeneratePublicCert("PEM", e.getMessage(), e);
    }
  }

  private void generateCertificateJks(Certificate certificate, GatewayConfig gatewayConfig) {
    try {
      if (jksFilePath == null || !jksFilePath.toFile().exists()) {
        jksFilePath = Paths.get(gatewayConfig.getGatewaySecurityDir(), "gateway-client-trust.jks");
        X509CertificateUtil.writeCertificateToJks(certificate, jksFilePath.toFile());
      }
    } catch (IOException | KeyStoreException | NoSuchAlgorithmException | CertificateException e) {
      LOG.failedToGeneratePublicCert("JKS", e.getMessage(), e);
    }
  }

  private String getBaseGatewayUrl(GatewayConfig config) {
    return request.getRequestURL().substring(0, request.getRequestURL().length() - request.getRequestURI().length()) + "/" + config.getGatewayPath();
  }

  @GET
  @Produces({ APPLICATION_XML, APPLICATION_JSON })
  @Path("topologies")
  public TopologyInformationWrapper getTopologies() {
    return getTopologies(null);
  }

  @GET
  @Produces({ APPLICATION_XML, APPLICATION_JSON })
  @Path("topologies/{name}")
  public TopologyInformationWrapper getTopology(@PathParam("name") String topologyName) {
    return getTopologies(topologyName);
  }

  private TopologyInformationWrapper getTopologies(String topologyName) {
    final TopologyInformationWrapper topologies = new TopologyInformationWrapper();
    final GatewayServices gatewayServices = (GatewayServices) request.getServletContext().getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
    final GatewayConfig config = (GatewayConfig) request.getServletContext().getAttribute(GatewayConfig.GATEWAY_CONFIG_ATTRIBUTE);
    final ServiceDefinitionRegistry serviceDefinitionRegistry = gatewayServices.getService(ServiceType.SERVICE_DEFINITION_REGISTRY);
    final Set<String> hiddenTopologies = config.getHiddenTopologiesOnHomepage();
    if (gatewayServices != null) {
      final TopologyService topologyService = gatewayServices.getService(ServiceType.TOPOLOGY_SERVICE);
      for (Topology topology : topologyService.getTopologies()) {
        if (!hiddenTopologies.contains(topology.getName()) && (topologyName == null || topology.getName().equalsIgnoreCase(topologyName))) {
          Set<ServiceModel> apiServices = new HashSet<>();
          Set<ServiceModel> uiServices = new HashSet<>();
          topology.getServices().stream().filter(service -> !UNREAL_SERVICES.contains(service.getRole())).forEach(service -> {
            service.getUrls().forEach(serviceUrl -> {
              ServiceModel serviceModel = getServiceModel(request, config.getGatewayPath(), topology.getName(), service, getServiceMetadata(serviceDefinitionRegistry, service),
                  serviceUrl);
              if (ServiceModel.Type.UI == serviceModel.getType()) {
                uiServices.add(serviceModel);
              } else if (ServiceModel.Type.API_AND_UI == serviceModel.getType()) {
                uiServices.add(serviceModel);
                apiServices.add(serviceModel);
              } else {
                apiServices.add(serviceModel);
              }
            });
          });
          topologies.addTopology(topology.getName(), isPinnedTopology(topology.getName(), config), new TreeSet<>(apiServices), new TreeSet<>(uiServices));
        }
      }
    }
    return topologies;
  }

  boolean isPinnedTopology(String topologyName, GatewayConfig config) {
    if (pinnedTopologies == null) {
      pinnedTopologies = config.getPinnedTopologiesOnHomepage();
    }
    return pinnedTopologies.contains(topologyName);
  }

  private Metadata getServiceMetadata(ServiceDefinitionRegistry serviceDefinitionRegistry, Service service) {
    final Optional<ServiceDefinitionPair> serviceDefinition = serviceDefinitionRegistry.getServiceDefinitions().stream()
        .filter(serviceDefinitionPair -> serviceDefinitionPair.getService().getRole().equalsIgnoreCase(service.getRole()))
        .filter(serviceDefinitionPair -> service.getVersion() == null || service.getVersion().toString().equalsIgnoreCase(serviceDefinitionPair.getService().getVersion()))
        .findFirst();
    return serviceDefinition.isPresent() ? serviceDefinition.get().getService().getMetadata() : null;
  }

  private ServiceModel getServiceModel(HttpServletRequest request, String gatewayPath, String topologyName, Service service, Metadata serviceMetadata, String serviceUrl) {
    final ServiceModel serviceModel = new ServiceModel();
    serviceModel.setRequest(request);
    serviceModel.setGatewayPath(gatewayPath);
    serviceModel.setTopologyName(topologyName);
    serviceModel.setService(service);
    serviceModel.setServiceMetadata(serviceMetadata);
    serviceModel.setServiceUrl(serviceUrl);
    return serviceModel;
  }

}
