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

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import javax.management.ObjectName;
import javax.management.QueryExp;

import org.apache.logging.log4j.Logger;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.MediaType;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;

import org.apache.geode.annotations.Immutable;
import org.apache.geode.internal.logging.LogService;
import org.apache.geode.internal.util.IOUtils;
import org.apache.geode.management.DistributedSystemMXBean;
import org.apache.geode.management.internal.MBeanJMXAdapter;
import org.apache.geode.management.internal.ManagementConstants;
import org.apache.geode.management.internal.cli.CommandRequest;
import org.apache.geode.management.internal.cli.shell.Gfsh;
import org.apache.geode.management.internal.cli.shell.OperationInvoker;
import org.apache.geode.management.internal.web.domain.QueryParameterSource;
import org.apache.geode.management.internal.web.http.support.HttpRequester;
import org.apache.geode.management.internal.web.shell.support.HttpMBeanProxyFactory;

/**
 * The HttpOperationInvoker class is an abstract base class encapsulating common functionality for
 * all HTTP-based OperationInvoker implementations.
 *
 * @see org.apache.geode.management.internal.cli.shell.Gfsh
 * @see org.apache.geode.management.internal.cli.shell.OperationInvoker
 * @see org.apache.geode.management.internal.web.shell.HttpOperationInvoker
 * @since GemFire 8.0
 */
@SuppressWarnings("unused")
public class HttpOperationInvoker implements OperationInvoker {

  protected static final long DEFAULT_INITIAL_DELAY = TimeUnit.SECONDS.toMillis(1);
  protected static final long DEFAULT_PERIOD = TimeUnit.MILLISECONDS.toMillis(2000);
  @Immutable
  protected static final TimeUnit DEFAULT_TIME_UNIT = TimeUnit.MILLISECONDS;
  protected static final String CMD_QUERY_PARAMETER = "cmd";
  protected static final String COMMANDS_URI = "/management/commands";
  protected static final String RESOURCES_REQUEST_PARAMETER = "resources";

  // the ID of the GemFire distributed system (cluster)
  private Integer clusterId = CLUSTER_ID_WHEN_NOT_CONNECTED;

  // Executor for scheduling periodic Runnable task to assess the state of the Manager's HTTP
  // service or Web Service
  private final ScheduledExecutorService executorService;

  // a reference to the GemFire shell (Gfsh) instance using this HTTP-based OperationInvoker for
  // command execution
  // and processing
  private final Gfsh gfsh;

  private final String baseUrl;

  // a Java Logger used to log severe, warning, informational and debug messages during the
  // operation of this invoker
  private final Logger logger = LogService.getLogger();

  // the Spring RestTemplate used to executeRequest HTTP requests and make REST API calls
  private volatile HttpRequester httpRequester;

  private boolean connected = false;

  /**
   * Constructs an instance of the HttpOperationInvoker class with a reference to the GemFire shell
   * (Gfsh) instance using this HTTP-based OperationInvoker to send commands to the GemFire Manager
   * via HTTP for procsessing along with the base URL to the GemFire Manager's embedded HTTP service
   * hosting the HTTP (REST) interface.
   *
   * @param gfsh a reference to the instance of the GemFire shell (Gfsh) using this HTTP-based
   *        OperationInvoker for command processing.
   * @param baseUrl a String specifying the base URL to the GemFire Manager's embedded HTTP service
   *        hosting the REST interface.
   * @throws AssertionError if the reference to the Gfsh instance is null.
   * @see org.apache.geode.management.internal.cli.shell.Gfsh
   */
  public HttpOperationInvoker(final Gfsh gfsh, final String baseUrl,
      Properties securityProperties) {
    this.gfsh = gfsh;
    this.baseUrl = baseUrl;
    this.httpRequester = new HttpRequester(securityProperties);

    // request ping and then schedule the ping to access the "alive" state, this will trigger
    // authentication check
    httpRequester.get(HttpRequester.createURI(baseUrl, "/ping"), String.class);
    connected = true;

    // constructs an instance of a single-threaded, scheduled Executor to send periodic HTTP
    // requests to the Manager's HTTP service or Web Service to assess the "alive" state
    this.executorService = Executors.newSingleThreadScheduledExecutor();
    executorService.scheduleAtFixedRate(() -> {
      try {
        httpRequester.get(HttpRequester.createURI(baseUrl, "/ping"), String.class);
      } catch (Exception e) {
        printDebug("An error occurred while connecting to the Manager's HTTP service: %1$s: ",
            e.getMessage());
        getGfsh().notifyDisconnect(HttpOperationInvoker.this.toString());
        stop();
      }
    }, DEFAULT_INITIAL_DELAY, DEFAULT_PERIOD, DEFAULT_TIME_UNIT);

    // initialize cluster id
    clusterId = (Integer) getAttribute(ManagementConstants.OBJECTNAME__DISTRIBUTEDSYSTEM_MXBEAN,
        "DistributedSystemId");
  }

  /**
   * Asserts whether state, based on the evaluation of a conditional expression, passed to this
   * assertion is valid.
   *
   * @param validState a boolean value indicating the evaluation of the expression from which the
   *        conditional state is based. For example, a caller might use an expression of the form
   *        (initableObj.isInitialized()).
   * @param message a String values used as the message when constructing an IllegalStateException.
   * @param args Object arguments used to populate placeholder's in the message.
   * @throws IllegalStateException if the conditional state is not valid.
   * @see java.lang.String#format(String, Object...)
   */
  protected static void assertState(final boolean validState, final String message,
      final Object... args) {
    if (!validState) {
      throw new IllegalStateException(String.format(message, args));
    }
  }

  /**
   * Determines whether Gfsh is in debug mode (or whether the user enabled debugging in Gfsh).
   *
   * @return a boolean value indicating if debugging has been turned on in Gfsh.
   * @see org.apache.geode.management.internal.cli.shell.Gfsh#getDebug()
   */
  protected boolean isDebugEnabled() {
    return getGfsh().getDebug();
  }

  /**
   * Gets the ExecutorService used by this HTTP OperationInvoker to scheduled periodic or delayed
   * tasks.
   *
   * @return an instance of the ScheduledExecutorService for scheduling periodic or delayed tasks.
   * @see java.util.concurrent.ScheduledExecutorService
   */
  protected ScheduledExecutorService getExecutorService() {
    return this.executorService;
  }

  /**
   * Returns the reference to the GemFire shell (Gfsh) instance using this HTTP-based
   * OperationInvoker to send commands to the GemFire Manager for remote execution and processing.
   *
   * @return a reference to the instance of the GemFire shell (Gfsh) using this HTTP-based
   *         OperationInvoker to process commands.
   * @see org.apache.geode.management.internal.cli.shell.Gfsh
   */
  protected Gfsh getGfsh() {
    return this.gfsh;
  }

  /**
   * Displays the message inside GemFire shell at debug level.
   *
   * @param message the String containing the message to display inside Gfsh.
   * @see #isDebugEnabled()
   * @see #printInfo(String, Object...)
   */
  protected void printDebug(final String message, final Object... args) {
    if (isDebugEnabled()) {
      printInfo(message, args);
    }
  }

  /**
   * Displays the message inside GemFire shell at info level.
   *
   * @param message the String containing the message to display inside Gfsh.
   * @see org.apache.geode.management.internal.cli.shell.Gfsh#printAsInfo(String)
   */
  protected void printInfo(final String message, final Object... args) {
    getGfsh().printAsInfo(String.format(message, args));
  }

  /**
   * Displays the message inside GemFire shell at warning level.
   *
   * @param message the String containing the message to display inside Gfsh.
   * @see org.apache.geode.management.internal.cli.shell.Gfsh#printAsWarning(String)
   */
  protected void printWarning(final String message, final Object... args) {
    getGfsh().printAsWarning(String.format(message, args));
  }

  /**
   * Displays the message inside GemFire shell at severe level.
   *
   * @param message the String containing the message to display inside Gfsh.
   * @see org.apache.geode.management.internal.cli.shell.Gfsh#printAsSevere(String)
   */
  protected void printSevere(final String message, final Object... args) {
    getGfsh().printAsSevere(String.format(message, args));
  }



  /**
   * Determines whether this HTTP-based OperationInvoker is successfully connected to the remote
   * GemFire Manager's HTTP service in order to send commands for execution/processing.
   *
   * @return a boolean value indicating the connection state of the HTTP-based OperationInvoker.
   */
  @Override
  public boolean isConnected() {
    return connected;
  }

  /**
   * Determines whether this HTTP-based OperationInvoker is ready to send commands to the GemFire
   * Manager for remote execution/processing.
   *
   * @return a boolean value indicating whether this HTTP-based OperationInvoker is ready for
   *         command invocations.
   * @see #isConnected()
   */
  @Override
  public boolean isReady() {
    return isConnected();
  }

  /**
   * Read the attribute identified by name from a remote resource identified by name. The intent of
   * this method is to return the value of an attribute on an MBean located in the remote
   * MBeanServer.
   *
   * @param resourceName name/url of the remote resource from which to fetch the attribute value.
   * @param attributeName name of the attribute who's value will be fetched.
   * @return the value of the named attribute for the named resource (typically an MBean).
   * @throws MBeanAccessException if an MBean access error occurs.
   */
  @Override
  public Object getAttribute(final String resourceName, final String attributeName) {
    final URI link = HttpRequester.createURI(baseUrl, "/mbean/attribute", "resourceName",
        resourceName, "attributeName", attributeName);

    try {
      return IOUtils.deserializeObject(httpRequester.get(link, byte[].class));
    } catch (IOException e) {
      throw new MBeanAccessException(String.format(
          "De-serializing the result of accessing attribute (%1$s) on MBean (%2$s) failed!",
          resourceName, attributeName), e);
    } catch (ClassNotFoundException e) {
      throw new MBeanAccessException(String.format(
          "The Class type of the result when accessing attribute (%1$s) on MBean (%2$s) was not found!",
          resourceName, attributeName), e);
    }
  }

  @Override
  public int getClusterId() {
    return clusterId;
  }

  /**
   * Gets a proxy to the remote DistributedSystem MXBean to access attributes and invoke operations
   * on the distributed system, or the GemFire cluster.
   *
   * @return a proxy instance of the GemFire Manager's DistributedSystem MXBean.
   * @see #getMBeanProxy(javax.management.ObjectName, Class)
   */
  @Override
  public DistributedSystemMXBean getDistributedSystemMXBean() {
    return getMBeanProxy(MBeanJMXAdapter.getDistributedSystemName(), DistributedSystemMXBean.class);
  }

  /**
   * Gets a proxy to an MXBean on a remote MBeanServer using HTTP for remoting.
   *
   * @param <T> the class type of the remote MXBean.
   * @param objectName the JMX ObjectName uniquely identifying the remote MXBean.
   * @param mbeanInterface the interface of the remote MXBean to proxy for attribute/operation
   *        access.
   * @return a proxy using HTTP remoting to access the specified, remote MXBean.
   * @see javax.management.ObjectName
   * @see org.apache.geode.management.internal.web.shell.support.HttpMBeanProxyFactory
   */
  @Override
  public <T> T getMBeanProxy(final ObjectName objectName, final Class<T> mbeanInterface) {
    return HttpMBeanProxyFactory.createMBeanProxy(this, objectName, mbeanInterface);
  }

  /**
   * Invoke an operation identified by name on a remote resource identified by name with the given
   * arguments. The intent of this method is to invoke an arbitrary operation on an MBean located in
   * the remote MBeanServer.
   *
   * @param resourceName name/url (object name) of the remote resource (MBea) on which operation is
   *        to be invoked.
   * @param operationName name of the operation to be invoked.
   * @param params an array of arguments for the parameters to be set when the operation is invoked.
   * @param signatures an array containing the signature of the operation.
   * @return result of the operation invocation.
   * @throws MBeanAccessException if an MBean access error occurs.
   */
  @Override
  public Object invoke(final String resourceName, final String operationName, final Object[] params,
      final String[] signatures) {
    final URI link = HttpRequester.createURI(baseUrl, "/mbean/operation");

    MultiValueMap<String, Object> content = new LinkedMultiValueMap<>();

    content.add("resourceName", resourceName);
    content.add("operationName", operationName);
    if (params != null) {
      for (Object param : params) {
        content.add("parameters", param);
      }
    }
    if (signatures != null) {
      for (String signature : signatures) {
        content.add("signature", signature);
      }
    }

    try {
      return IOUtils.deserializeObject(
          httpRequester.post(link, MediaType.MULTIPART_FORM_DATA, content, byte[].class));
    } catch (IOException e) {
      throw new MBeanAccessException(String.format(
          "De-serializing the result from invoking operation (%1$s) on MBean (%2$s) failed!",
          resourceName, operationName), e);
    } catch (ClassNotFoundException e) {
      throw new MBeanAccessException(String.format(
          "The Class type of the result from invoking operation (%1$s) on MBean (%2$s) was not found!",
          resourceName, operationName), e);
    }

  }

  /**
   * This method searches the MBean server, based on the OperationsInvoker's JMX-based or remoting
   * capable MBean server connection, for MBeans matching a specific ObjectName or matching an
   * ObjectName pattern along with satisfying criteria from the Query expression.
   *
   * @param objectName the ObjectName or pattern for which matching MBeans in the target MBean
   *        server will be returned.
   * @param queryExpression the JMX-based query expression used to filter matching MBeans.
   * @return a set of ObjectName's matching MBeans in the MBean server matching the ObjectName and
   *         Query expression criteria.
   */
  @Override
  @SuppressWarnings("unchecked")
  public Set<ObjectName> queryNames(final ObjectName objectName, final QueryExp queryExpression) {
    final URI link = HttpRequester.createURI(baseUrl, "/mbean/query");

    Object content = new QueryParameterSource(objectName, queryExpression);
    try {
      return (Set<ObjectName>) IOUtils
          .deserializeObject(httpRequester.post(link, null, content, byte[].class));
    } catch (Exception e) {
      throw new MBeanAccessException(String.format(
          "An error occurred while querying for MBean names using ObjectName pattern (%1$s) and Query expression (%2$s)!",
          objectName, queryExpression), e);
    }
  }

  /**
   * Stops communication with and closes all connections to the remote HTTP server (service).
   */
  @Override
  public void stop() {
    if (executorService != null) {
      executorService.shutdown();
    }
    httpRequester = null;
    connected = false;
  }

  @Override
  public String toString() {
    return String.format("GemFire Manager HTTP service @ %1$s", baseUrl);
  }

  @Override
  public String getRemoteVersion() {
    final URI link = HttpRequester.createURI(baseUrl, "/version/release");
    return httpRequester.get(link, String.class);
  }


  /**
   * Processes the requested command. Sends the command to the GemFire Manager for remote processing
   * (execution).
   *
   * @param command the command requested/entered by the user to be processed.
   * @return the result of the command execution, either a json string of ResultModel or a Path
   */
  @Override
  public Object processCommand(final CommandRequest command) {
    URI link =
        HttpRequester.createURI(baseUrl, COMMANDS_URI, CMD_QUERY_PARAMETER, command.getUserInput());
    if (command.hasFileList()) {
      MultiValueMap<String, Object> content = new LinkedMultiValueMap<String, Object>();

      for (File file : command.getFileList()) {
        content.add(RESOURCES_REQUEST_PARAMETER, new FileSystemResource(file));
      }
      return httpRequester.post(link, MediaType.MULTIPART_FORM_DATA, content, String.class);
    }

    // when no file data to upload, this handles file download over http
    return httpRequester.executeWithResponseExtractor(link);
  }
}
