/*
 * 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.solr.cloud.autoscaling;

import java.io.Closeable;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import org.apache.lucene.store.AlreadyClosedException;
import org.apache.solr.client.solrj.cloud.SolrCloudManager;
import org.apache.solr.client.solrj.cloud.autoscaling.TriggerEventType;
import org.apache.solr.common.util.Utils;
import org.apache.solr.core.SolrResourceLoader;

/**
 * Common autoscaling interfaces.
 *
 * @deprecated to be removed in Solr 9.0 (see SOLR-14656)
 */
public class AutoScaling {

  /**
   * Implementation of this interface is used for processing events generated by a trigger.
   */
  public interface TriggerEventProcessor {

    /**
     * This method is executed for events produced by {@link Trigger#run()}.
     *
     * @param event a subclass of {@link TriggerEvent}
     * @return true if the processor was ready to perform actions on the event, false
     * otherwise. If false was returned then callers should assume the event was discarded.
     */
    boolean process(TriggerEvent event);
  }

  /**
   * Interface for a Solr trigger. Each trigger implements Runnable and Closeable interface. A trigger
   * is scheduled using a {@link java.util.concurrent.ScheduledExecutorService} so it is executed as
   * per a configured schedule to check whether the trigger is ready to fire. The {@link AutoScaling.Trigger#setProcessor(AutoScaling.TriggerEventProcessor)}
   * method should be used to set a processor which is used by implementation of this class whenever
   * ready.
   * <p>
   * As per the guarantees made by the {@link java.util.concurrent.ScheduledExecutorService} a trigger
   * implementation is only ever called sequentially and therefore need not be thread safe. However, it
   * is encouraged that implementations be immutable with the exception of the associated listener
   * which can be get/set by a different thread than the one executing the trigger. Therefore, implementations
   * should use appropriate synchronization around the listener.
   * <p>
   * When a trigger is ready to fire, it calls the {@link TriggerEventProcessor#process(TriggerEvent)} event
   * with the proper trigger event object. If that method returns false then it should be interpreted to mean
   * that Solr is not ready to process this trigger event and therefore we should retain the state and fire
   * at the next invocation of the run() method.
   */
  public interface Trigger extends Closeable, Runnable {
    /**
     * Trigger name.
     */
    String getName();

    /**
     * Event type generated by this trigger.
     */
    TriggerEventType getEventType();

    /** Returns true if this trigger is enabled. */
    boolean isEnabled();

    /** Trigger properties. */
    Map<String, Object> getProperties();

    /** Number of seconds to wait between fired events ("waitFor" property). */
    int getWaitForSecond();

    /** Actions to execute when event is fired. */
    List<TriggerAction> getActions();

    /** Set event processor to call when event is fired. */
    void setProcessor(TriggerEventProcessor processor);

    /** Get event processor. */
    TriggerEventProcessor getProcessor();

    /** Return true when this trigger is closed and cannot be used. */
    boolean isClosed();

    /** Set internal state of this trigger from another instance. */
    void restoreState(Trigger old);

    /** Save internal state of this trigger in ZooKeeper. */
    void saveState();

    /** Restore internal state of this trigger from ZooKeeper. */
    void restoreState();

    /**
     * Called when trigger is created but before it's initialized or scheduled for use.
     * This method should also verify that the trigger configuration parameters are correct. It may
     * be called multiple times.
     * @param properties configuration properties
     * @throws TriggerValidationException contains details of invalid configuration parameters.
     */
    void configure(SolrResourceLoader loader, SolrCloudManager cloudManager, Map<String, Object> properties) throws TriggerValidationException;

    /**
     * Called before a trigger is scheduled. Any heavy object creation or initialisation should
     * be done in this method instead of the Trigger's constructor.
     */
    void init() throws Exception;
  }

  /**
   * Factory to produce instances of {@link Trigger}.
   */
  public static abstract class TriggerFactory implements Closeable {
    protected boolean isClosed = false;

    public abstract Trigger create(TriggerEventType type, String name, Map<String, Object> props) throws TriggerValidationException;

    @Override
    public void close() throws IOException {
      synchronized (this) {
        isClosed = true;
      }
    }
  }

  /**
   * Default implementation of {@link TriggerFactory}.
   */
  public static class TriggerFactoryImpl extends TriggerFactory {

    private final SolrCloudManager cloudManager;
    private final SolrResourceLoader loader;

    public TriggerFactoryImpl(SolrResourceLoader loader, SolrCloudManager cloudManager) {
      Objects.requireNonNull(cloudManager);
      Objects.requireNonNull(loader);
      this.cloudManager = cloudManager;
      this.loader = loader;
    }

    @Override
    public synchronized Trigger create(TriggerEventType type, String name, Map<String, Object> props) throws TriggerValidationException {
      if (isClosed) {
        throw new AlreadyClosedException("TriggerFactory has already been closed, cannot create new triggers");
      }
      if (type == null) {
        throw new IllegalArgumentException("Trigger type must not be null");
      }
      if (name == null || name.isEmpty()) {
        throw new IllegalArgumentException("Trigger name must not be empty");
      }
      Trigger t;
      switch (type) {
        case NODEADDED:
          t = new NodeAddedTrigger(name);
          break;
        case NODELOST:
          t = new NodeLostTrigger(name);
        break;
        case SEARCHRATE:
          t = new SearchRateTrigger(name);
        break;
        case METRIC:
          t = new MetricTrigger(name);
        break;
        case SCHEDULED:
          t = new ScheduledTrigger(name);
        break;
        case INDEXSIZE:
          t = new IndexSizeTrigger(name);
          break;
        default:
          throw new IllegalArgumentException("Unknown event type: " + type + " in trigger: " + name);
      }
      t.configure(loader, cloudManager, props);
      return t;
    }

  }

  public static final String AUTO_ADD_REPLICAS_TRIGGER_NAME = ".auto_add_replicas";

  public static final String AUTO_ADD_REPLICAS_TRIGGER_DSL =
      "    {" +
      "        'name' : '" + AUTO_ADD_REPLICAS_TRIGGER_NAME + "'," +
      "        'event' : 'nodeLost'," +
      "        'waitFor' : -1," +
      "        'enabled' : true," +
      "        'actions' : [" +
      "            {" +
      "                'name':'auto_add_replicas_plan'," +
      "                'class':'solr.AutoAddReplicasPlanAction'" +
      "            }," +
      "            {" +
      "                'name':'execute_plan'," +
      "                'class':'solr.ExecutePlanAction'" +
      "            }" +
      "        ]" +
      "    }";

  @SuppressWarnings({"unchecked"})
  public static final Map<String, Object> AUTO_ADD_REPLICAS_TRIGGER_PROPS = (Map) Utils.fromJSONString(AUTO_ADD_REPLICAS_TRIGGER_DSL);

  public static final String SCHEDULED_MAINTENANCE_TRIGGER_NAME = ".scheduled_maintenance";

  public static final String SCHEDULED_MAINTENANCE_TRIGGER_DSL =
          "    {" +
          "        'name' : '" + SCHEDULED_MAINTENANCE_TRIGGER_NAME + "'," +
          "        'event' : 'scheduled'," +
          "        'startTime' : 'NOW'," +
          "        'every' : '+1DAY'," +
          "        'enabled' : true," +
          "        'actions' : [" +
          "            {" +
          "                'name':'inactive_shard_plan'," +
          "                'class':'solr.InactiveShardPlanAction'" +
          "            }," +
          "            {" +
          "                'name':'inactive_markers_plan'," +
          "                'class':'solr.InactiveMarkersPlanAction'" +
          "            }," +
          "            {" +
          "                'name':'execute_plan'," +
          "                'class':'solr.ExecutePlanAction'" +
          "            }" +
          "        ]" +
          "    }";

  @SuppressWarnings({"unchecked"})
  public static final Map<String, Object> SCHEDULED_MAINTENANCE_TRIGGER_PROPS = (Map) Utils.fromJSONString(SCHEDULED_MAINTENANCE_TRIGGER_DSL);

}
