/*
 * 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.cli.functions;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import joptsimple.internal.Strings;
import org.apache.logging.log4j.Logger;

import org.apache.geode.cache.CacheClosedException;
import org.apache.geode.cache.Declarable;
import org.apache.geode.cache.asyncqueue.AsyncEventListener;
import org.apache.geode.cache.asyncqueue.AsyncEventQueueFactory;
import org.apache.geode.cache.configuration.CacheConfig;
import org.apache.geode.cache.configuration.ClassNameType;
import org.apache.geode.cache.configuration.DeclarableType;
import org.apache.geode.cache.configuration.ParameterType;
import org.apache.geode.cache.execute.FunctionContext;
import org.apache.geode.cache.wan.GatewayEventFilter;
import org.apache.geode.cache.wan.GatewayEventSubstitutionFilter;
import org.apache.geode.cache.wan.GatewaySender.OrderPolicy;
import org.apache.geode.distributed.DistributedMember;
import org.apache.geode.internal.ClassPathLoader;
import org.apache.geode.internal.InternalDataSerializer;
import org.apache.geode.internal.cache.InternalCache;
import org.apache.geode.internal.logging.LogService;
import org.apache.geode.management.cli.CliFunction;
import org.apache.geode.management.internal.cli.functions.CliFunctionResult.StatusState;

/**
 * Function used by the 'create async-event-queue' gfsh command to create an asynchronous event
 * queue on a member.
 *
 * @since GemFire 8.0
 */
public class CreateAsyncEventQueueFunction extends CliFunction {
  private static final Logger logger = LogService.getLogger();

  private static final long serialVersionUID = 1L;

  @Override
  public CliFunctionResult executeFunction(FunctionContext context) {
    // Declared here so that it's available when returning a Throwable
    String memberId = "";

    try {
      CacheConfig.AsyncEventQueue config = (CacheConfig.AsyncEventQueue) context.getArguments();

      InternalCache cache = (InternalCache) context.getCache();

      DistributedMember member = cache.getDistributedSystem().getDistributedMember();

      memberId = member.getId();
      // If they set a name use it instead
      if (!member.getName().equals("")) {
        memberId = member.getName();
      }

      AsyncEventQueueFactory asyncEventQueueFactory =
          cache.createAsyncEventQueueFactory().setParallel(config.isParallel())
              .setBatchConflationEnabled(config.isEnableBatchConflation())
              .setBatchSize(Integer.parseInt(config.getBatchSize()))
              .setBatchTimeInterval(Integer.parseInt(config.getBatchTimeInterval()))
              .setPersistent(config.isPersistent()).setDiskStoreName(config.getDiskStoreName())
              .setDiskSynchronous(config.isDiskSynchronous())
              .setForwardExpirationDestroy(config.isForwardExpirationDestroy())
              .setMaximumQueueMemory(Integer.parseInt(config.getMaximumQueueMemory()))
              .setDispatcherThreads(Integer.parseInt(config.getDispatcherThreads()))
              .setOrderPolicy(OrderPolicy.valueOf(config.getOrderPolicy()));

      if (config.isPauseEventProcessing()) {
        asyncEventQueueFactory.pauseEventDispatching();
      }

      String[] gatewayEventFilters = config.getGatewayEventFilters().stream()
          .map(ClassNameType::getClassName).toArray(String[]::new);

      if (gatewayEventFilters != null) {
        for (String gatewayEventFilter : gatewayEventFilters) {
          asyncEventQueueFactory
              .addGatewayEventFilter((GatewayEventFilter) newInstance(gatewayEventFilter));
        }
      }

      DeclarableType gatewayEventSubstitutionFilter = config.getGatewayEventSubstitutionFilter();

      if (gatewayEventSubstitutionFilter != null) {
        String gatewaySubstitutionFilter = gatewayEventSubstitutionFilter.getClassName();
        asyncEventQueueFactory.setGatewayEventSubstitutionListener(
            (GatewayEventSubstitutionFilter<?, ?>) newInstance(gatewaySubstitutionFilter));
      }

      String listenerClassName = config.getAsyncEventListener().getClassName();
      Object listenerInstance;
      Class<?> listenerClass = InternalDataSerializer.getCachedClass(listenerClassName);
      listenerInstance = listenerClass.newInstance();

      List<ParameterType> parameters = config.getAsyncEventListener().getParameters();
      Properties listenerProperties = new Properties();
      for (ParameterType p : parameters) {
        listenerProperties.put(p.getName(), p.getString());
      }

      if (!listenerProperties.isEmpty()) {
        if (!(listenerInstance instanceof Declarable)) {
          throw new IllegalArgumentException(
              "Listener properties were provided, but the listener specified does not implement Declarable.");
        }

        ((Declarable) listenerInstance).initialize(cache, listenerProperties);
        ((Declarable) listenerInstance).init(listenerProperties); // for backwards compatibility

        Map<Declarable, Properties> declarablesMap = new HashMap<>();
        declarablesMap.put((Declarable) listenerInstance, listenerProperties);
        cache.addDeclarableProperties(declarablesMap);
      }

      asyncEventQueueFactory.create(config.getId(), (AsyncEventListener) listenerInstance);

      return new CliFunctionResult(memberId, StatusState.OK, "Success");
    } catch (CacheClosedException cce) {
      return new CliFunctionResult(memberId, StatusState.ERROR, null);
    } catch (Exception e) {
      logger.error("Could not create async event queue: {}", e.getMessage(), e);
      return new CliFunctionResult(memberId, e, null);
    }
  }

  private Object newInstance(String className)
      throws ClassNotFoundException, IllegalAccessException, InstantiationException {
    if (Strings.isNullOrEmpty(className)) {
      return null;
    }

    return ClassPathLoader.getLatest().forName(className).newInstance();
  }

  @Override
  public String getId() {
    return CreateAsyncEventQueueFunction.class.getName();
  }
}
