/*
 * 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;

import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Locale;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.solr.common.cloud.ClusterState;
import org.apache.solr.common.cloud.DocCollection;
import org.apache.solr.common.cloud.DocRouter;
import org.apache.solr.common.cloud.Replica;
import org.apache.solr.common.cloud.Slice;
import org.apache.solr.common.cloud.ZkStateReader;
import org.apache.solr.common.util.Utils;

/**
 * A utility class that can create mock ZkStateReader objects with custom ClusterState objects created
 * using a simple string based description. See {@link #buildClusterState(String, int, int, String...)} for
 * details on how the cluster state can be created.
 *
 * @lucene.experimental
 */
public class ClusterStateMockUtil {

  private final static Pattern BLUEPRINT = Pattern.compile("([a-z])(\\d+)?(?:(['A','R','D','F']))?(\\*)?");

  public static ZkStateReader buildClusterState(String clusterDescription, String ... liveNodes) {
    return buildClusterState(clusterDescription, 1, liveNodes);
  }

  public static ZkStateReader buildClusterState(String clusterDescription, int replicationFactor, String ... liveNodes) {
    return buildClusterState(clusterDescription, replicationFactor, 10, liveNodes);
  }

  /**
   * This method lets you construct a complex ClusterState object by using simple strings of letters.
   *
   * c = collection, s = slice, r = replica (nrt type, default), n = nrt replica, t = tlog replica, p = pull replica, \d = node number (r2 means the replica is on node 2),
   * state = [A,R,D,F], * = replica to replace, binds to the left.
   *
   * For example:
   * csrr2rD*sr2csr
   *
   * Creates:
   *
   * 'csrr2rD*'
   * A collection, a shard, a replica on node 1 (the default) that is active (the default), a replica on node 2, and a replica on node 1
   * that has a state of down and is the replica we will be looking to put somewhere else (the *).
   *
   * 'sr2'
   * Then, another shard that has a replica on node 2.
   *
   * 'csr'
   * Then, another collection that has a shard with a single active replica on node 1.
   *
   * Result:
   *        {
   *         "collection2":{
   *           "maxShardsPerNode":"1",
   *           "replicationFactor":"1",
   *           "shards":{"slice1":{
   *               "state":"active",
   *               "replicas":{"replica5":{
   *                   "state":"active",
   *                   "node_name":"baseUrl1_",
   *                   "base_url":"http://baseUrl1"}}}}},
   *         "collection1":{
   *           "maxShardsPerNode":"1",
   *           "replicationFactor":"1",
   *           "shards":{
   *             "slice1":{
   *               "state":"active",
   *               "replicas":{
   *                 "replica3 (bad)":{
   *                   "state":"down",
   *                   "node_name":"baseUrl1_",
   *                   "base_url":"http://baseUrl1"},
   *                 "replica2":{
   *                   "state":"active",
   *                   "node_name":"baseUrl2_",
   *                   "base_url":"http://baseUrl2"},
   *                 "replica1":{
   *                   "state":"active",
   *                   "node_name":"baseUrl1_",
   *                   "base_url":"http://baseUrl1"}}},
   *             "slice2":{
   *               "state":"active",
   *               "replicas":{"replica4":{
   *                   "state":"active",
   *                   "node_name":"baseUrl2_",
   *                   "base_url":"http://baseUrl2"}}}}}}
   *
   */
  @SuppressWarnings("resource")
  public static ZkStateReader buildClusterState(String clusterDescription, int replicationFactor, int maxShardsPerNode, String ... liveNodes) {
    Map<String,Slice> slices = null;
    Map<String,Replica> replicas = null;
    Map<String,Object> collectionProps = new HashMap<>();
    collectionProps.put(ZkStateReader.MAX_SHARDS_PER_NODE, Integer.toString(maxShardsPerNode));
    collectionProps.put(ZkStateReader.REPLICATION_FACTOR, Integer.toString(replicationFactor));
    Map<String,DocCollection> collectionStates = new HashMap<>();
    DocCollection docCollection = null;
    String collName = null;
    String sliceName = null;
    Slice slice = null;
    int replicaCount = 1;

    Matcher m = BLUEPRINT.matcher(clusterDescription);
    while (m.find()) {
      Replica replica;
      switch (m.group(1)) {
        case "c":
          slices = new HashMap<>();
          docCollection = new DocCollection(collName = "collection" + (collectionStates.size() + 1), slices, collectionProps, DocRouter.DEFAULT);
          collectionStates.put(docCollection.getName(), docCollection);
          break;
        case "s":
          replicas = new HashMap<>();
          if(collName == null) collName = "collection" + (collectionStates.size() + 1);
          slice = new Slice(sliceName = "slice" + (slices.size() + 1), replicas, null,  collName);
          slices.put(slice.getName(), slice);

          // hack alert: the DocCollection constructor copies over active slices to its active slice map in the constructor
          // but here we construct the DocCollection before creating the slices which breaks code that calls DocCollection.getActiveSlices
          // so here we re-create doc collection with the latest slices map to workaround this problem
          // todo: a better fix would be to have a builder class for DocCollection that builds the final object once all the slices and replicas have been created.
          docCollection = docCollection.copyWithSlices(slices);
          collectionStates.put(docCollection.getName(), docCollection);
          break;
        case "r":
        case "n":
        case "t":
        case "p":
          String node = m.group(2);
          String replicaName = "replica" + replicaCount++;
          String stateCode = m.group(3);

          Map<String, Object> replicaPropMap = makeReplicaProps(sliceName, node, replicaName, stateCode, m.group(1));
          if (collName == null) collName = "collection" + (collectionStates.size() + 1);
          if (sliceName == null) collName = "slice" + (slices.size() + 1);

          // O(n^2) alert! but this is for mocks and testing so shouldn't be used for very large cluster states
          boolean leaderFound = false;
          for (Map.Entry<String, Replica> entry : replicas.entrySet()) {
            Replica value = entry.getValue();
            if ("true".equals(value.get(Slice.LEADER)))  {
              leaderFound = true;
              break;
            }
          }
          if (!leaderFound && !m.group(1).equals("p")) {
            replicaPropMap.put(Slice.LEADER, "true");
          }
          replica = new Replica(replicaName, replicaPropMap, collName, sliceName);
          replicas.put(replica.getName(), replica);

          // hack alert: re-create slice with existing data and new replicas map so that it updates its internal leader attribute
          slice = new Slice(slice.getName(), replicas, null, collName);
          slices.put(slice.getName(), slice);
          // we don't need to update doc collection again because we aren't adding a new slice or changing its state
          break;
        default:
          break;
      }
    }

    ClusterState clusterState = new ClusterState(1, new HashSet<>(Arrays.asList(liveNodes)), collectionStates);
    MockZkStateReader reader = new MockZkStateReader(clusterState, collectionStates.keySet());

    String json;
    json = new String(Utils.toJSON(clusterState), StandardCharsets.UTF_8);
    System.err.println(json);

    return reader;
  }

  private static Map<String, Object> makeReplicaProps(String sliceName, String node, String replicaName, String stateCode, String replicaTypeCode) {
    if (node == null || node.trim().length() == 0) {
      node = "1";
    }

    Replica.State state = Replica.State.ACTIVE;
    if (stateCode != null) {
      switch (stateCode.charAt(0)) {
        case 'S':
          state = Replica.State.ACTIVE;
          break;
        case 'R':
          state = Replica.State.RECOVERING;
          break;
        case 'D':
          state = Replica.State.DOWN;
          break;
        case 'F':
          state = Replica.State.RECOVERY_FAILED;
          break;
        default:
          throw new IllegalArgumentException(
              "Unexpected state for replica: " + stateCode);
      }
    }

    Replica.Type replicaType = Replica.Type.NRT;
    switch (replicaTypeCode)  {
      case "t":
        replicaType = Replica.Type.TLOG;
        break;
      case "p":
        replicaType = Replica.Type.PULL;
        break;
    }

    Map<String,Object> replicaPropMap = new HashMap<>();
    int port = 8982 + Integer.parseInt(node);
    String nodeName = String.format(Locale.ROOT, "baseUrl%s:%d_", node, port);
    replicaPropMap.put(ZkStateReader.NODE_NAME_PROP, nodeName);
    replicaPropMap.put(ZkStateReader.STATE_PROP, state.toString());
    replicaPropMap.put(ZkStateReader.CORE_NAME_PROP, sliceName + "_" + replicaName);
    replicaPropMap.put(ZkStateReader.REPLICA_TYPE, replicaType.name());
    return replicaPropMap;
  }


}
