/*
 * 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.drill.exec.client;

import java.util.Map;
import java.util.Set;

import org.apache.drill.common.Version;
import org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos;
import org.apache.drill.exec.proto.UserProtos.RpcType;
import org.apache.drill.exec.rpc.user.UserRpcUtils;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;

/**
 * A enumeration of server methods, and the version they were introduced
 *
 * it allows to introduce new methods without changing the protocol, with client
 * being able to gracefully handle cases were method is not handled by the server.
 */
public enum ServerMethod {
  /**
   * Submitting a query
   */
  RUN_QUERY(RpcType.RUN_QUERY, Constants.DRILL_0_0_0),

  /**
   * Plan a query without executing it
   */
  PLAN_QUERY(RpcType.QUERY_PLAN_FRAGMENTS, Constants.DRILL_0_0_0),

  /**
   * Cancel an existing query
   */
  CANCEL_QUERY(RpcType.CANCEL_QUERY, Constants.DRILL_0_0_0),

  /**
   * Resume a query
   */
  RESUME_PAUSED_QUERY(RpcType.RESUME_PAUSED_QUERY, Constants.DRILL_0_0_0),

  /**
   * Prepare a query for deferred execution
   */
  PREPARED_STATEMENT(RpcType.CREATE_PREPARED_STATEMENT, Constants.DRILL_1_8_0),

  /**
   * Get catalog metadata
   */
  GET_CATALOGS(RpcType.GET_CATALOGS, Constants.DRILL_1_8_0),

  /**
   * Get schemas metadata
   */
  GET_SCHEMAS(RpcType.GET_SCHEMAS, Constants.DRILL_1_8_0),

  /**
   * Get tables metadata
   */
  GET_TABLES(RpcType.GET_TABLES, Constants.DRILL_1_8_0),

  /**
   * Get columns metadata
   */
  GET_COLUMNS(RpcType.GET_COLUMNS, Constants.DRILL_1_8_0),

  /**
   * Get server metadata
   */
  GET_SERVER_META(RpcType.GET_SERVER_META, Constants.DRILL_1_10_0);

  private static class Constants {
    private static final Version DRILL_0_0_0 = new Version("0.0.0", 0, 0, 0, 0, "");
    private static final Version DRILL_1_8_0 = new Version("1.8.0", 1, 8, 0, 0, "");
    private static final Version DRILL_1_10_0 = new Version("1.10.0", 1, 10, 0, 0, "");
  }

  private static final Map<RpcType, ServerMethod> REVERSE_MAPPING;
  static {
    ImmutableMap.Builder<RpcType, ServerMethod> builder = ImmutableMap.builder();
    for(ServerMethod method: values()) {
      builder.put(method.rpcType, method);
    }
    REVERSE_MAPPING = Maps.immutableEnumMap(builder.build());
  }

  private final RpcType rpcType;
  private final Version minVersion;

  private ServerMethod(RpcType rpcType, Version minVersion) {
    this.rpcType = rpcType;
    this.minVersion = minVersion;
  }

  public Version getMinVersion() {
    return minVersion;
  }

  /**
   * Returns the list of methods supported by the server based on its advertised information.
   *
   * @param serverInfos the server information
   * @return a immutable set of capabilities
   */
  static final Set<ServerMethod> getSupportedMethods(Iterable<RpcType> supportedMethods, RpcEndpointInfos serverInfos) {
    ImmutableSet.Builder<ServerMethod> builder = ImmutableSet.builder();

    for(RpcType supportedMethod: supportedMethods) {
      ServerMethod method = REVERSE_MAPPING.get(supportedMethod);
      if (method == null) {
        // The server might have newer methods we don't know how to handle yet.
        continue;
      }
      builder.add(method);
    }

    // Fallback to version detection to cover the gap between Drill 1.8.0 and Drill 1.10.0
    if (serverInfos == null) {
      return Sets.immutableEnumSet(builder.build());
    }

    Version serverVersion = UserRpcUtils.getVersion(serverInfos);
    for(ServerMethod capability: ServerMethod.values()) {
      if (serverVersion.compareTo(capability.getMinVersion()) >= 0) {
        builder.add(capability);
      }
    }

    return Sets.immutableEnumSet(builder.build());
  }
}
