/*
 * 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.geode.management.internal;

import java.net.URI;
import java.net.UnknownHostException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.Logger;

import org.apache.geode.cache.AttributesFactory;
import org.apache.geode.cache.CacheFactory;
import org.apache.geode.cache.DataPolicy;
import org.apache.geode.cache.RegionAttributes;
import org.apache.geode.cache.Scope;
import org.apache.geode.cache.internal.HttpService;
import org.apache.geode.distributed.internal.DistributionConfig;
import org.apache.geode.internal.GemFireVersion;
import org.apache.geode.internal.cache.InternalCache;
import org.apache.geode.internal.cache.InternalRegionArguments;
import org.apache.geode.internal.net.SocketCreator;
import org.apache.geode.internal.security.SecurityService;
import org.apache.geode.logging.internal.log4j.api.LogService;

/**
 * Agent implementation that controls the HTTP server end points used for REST clients to connect
 * gemfire data node.
 * <p>
 * The RestAgent is used to start http service in embedded mode on any non manager data node with
 * developer REST APIs service enabled.
 *
 * @since GemFire 8.0
 */
public class RestAgent {
  private static final Logger logger = LogService.getLogger();

  private boolean running = false;
  private final DistributionConfig config;
  private final SecurityService securityService;

  public RestAgent(DistributionConfig config, SecurityService securityService) {
    this.config = config;
    this.securityService = securityService;
  }

  public synchronized boolean isRunning() {
    return this.running;
  }


  public synchronized void start(InternalCache cache) {
    if (!this.running && this.config.getHttpServicePort() != 0) {
      try {
        startHttpService(cache);
        this.running = true;
        cache.setRESTServiceRunning(true);

        // create region to hold query information (queryId, queryString). Added
        // for the developer REST APIs
        RestAgent.createParameterizedQueryRegion();
      } catch (Throwable e) {
        logger.warn("Unable to start dev REST API: {}", e.toString());
      }
    }
  }

  private final String GEMFIRE_VERSION = GemFireVersion.getGemFireVersion();
  private AgentUtil agentUtil = new AgentUtil(GEMFIRE_VERSION);

  private boolean isRunningInTomcat() {
    return (System.getProperty("catalina.base") != null
        || System.getProperty("catalina.home") != null);
  }

  // Start HTTP service in embedded mode
  public void startHttpService(InternalCache cache) throws Exception {
    // Find the developer REST WAR file
    final URI gemfireAPIWar = agentUtil.findWarLocation("geode-web-api");
    if (gemfireAPIWar == null) {
      logger.info(
          "Unable to find GemFire Developer REST API WAR file; the Developer REST Interface for GemFire will not be accessible.");
    }

    // Check if we're already running inside Tomcat
    if (isRunningInTomcat()) {
      logger.warn(
          "Detected presence of catalina system properties. HTTP service will not be started. To enable the GemFire Developer REST API, please deploy the /geode-web-api WAR file in your application server.");
    } else if (agentUtil.isAnyWarFileAvailable(gemfireAPIWar)) {

      Map<String, Object> securityServiceAttr = new HashMap<>();
      securityServiceAttr.put(HttpService.SECURITY_SERVICE_SERVLET_CONTEXT_PARAM,
          securityService);

      if (cache.getOptionalService(HttpService.class).isPresent()) {
        HttpService httpService = cache.getOptionalService(HttpService.class).get();
        Path gemfireAPIWarPath = Paths.get(gemfireAPIWar);
        httpService.addWebApplication("/gemfire-api", gemfireAPIWarPath, securityServiceAttr);
        httpService.addWebApplication("/geode", gemfireAPIWarPath, securityServiceAttr);
      } else {
        logger.warn("HttpService is not available - could not start Dev REST API");
      }
    }
  }

  public static String getBindAddressForHttpService(DistributionConfig config) {
    String bindAddress = config.getHttpServiceBindAddress();
    if (StringUtils.isNotBlank(bindAddress))
      return bindAddress;

    bindAddress = config.getServerBindAddress();
    if (StringUtils.isNotBlank(bindAddress))
      return bindAddress;

    bindAddress = config.getBindAddress();
    if (StringUtils.isNotBlank(bindAddress))
      return bindAddress;

    try {
      bindAddress = SocketCreator.getLocalHost().getHostAddress();
      logger.info("RestAgent.getBindAddressForHttpService.localhost: "
          + SocketCreator.getLocalHost().getHostAddress());
    } catch (UnknownHostException e) {
      logger.error("LocalHost could not be found.", e);
    }
    return bindAddress;
  }

  /**
   * This method will create a REPLICATED region named _ParameterizedQueries__. In developer REST
   * APIs, this region will be used to store the queryId and queryString as a key and value
   * respectively.
   */
  public static void createParameterizedQueryRegion() {
    try {
      if (logger.isDebugEnabled()) {
        logger.debug("Starting creation of  __ParameterizedQueries__ region");
      }
      InternalCache cache = (InternalCache) CacheFactory.getAnyInstance();
      if (cache != null) {
        final InternalRegionArguments regionArguments = new InternalRegionArguments();
        regionArguments.setIsUsedForMetaRegion(true);
        final AttributesFactory<String, String> attributesFactory =
            new AttributesFactory<String, String>();

        attributesFactory.setConcurrencyChecksEnabled(false);
        attributesFactory.setDataPolicy(DataPolicy.REPLICATE);
        attributesFactory.setKeyConstraint(String.class);
        attributesFactory.setScope(Scope.DISTRIBUTED_ACK);
        attributesFactory.setStatisticsEnabled(false);
        attributesFactory.setValueConstraint(String.class);

        final RegionAttributes<String, String> regionAttributes = attributesFactory.create();

        cache.createVMRegion("__ParameterizedQueries__", regionAttributes, regionArguments);
        if (logger.isDebugEnabled()) {
          logger.debug("Successfully created __ParameterizedQueries__ region");
        }
      } else {
        logger.error("Cannot create ParameterizedQueries Region as no cache found!");
      }
    } catch (Exception e) {
      if (logger.isDebugEnabled()) {
        logger.debug("Error creating __ParameterizedQueries__ Region with cause {}", e.getMessage(),
            e);
      }
    }
  }
}
