/*
 * 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.iotdb.confignode.conf;

import org.apache.iotdb.commons.conf.CommonDescriptor;
import org.apache.iotdb.commons.conf.IoTDBConstant;
import org.apache.iotdb.commons.exception.BadNodeUrlException;
import org.apache.iotdb.commons.utils.NodeUrlUtils;
import org.apache.iotdb.confignode.manager.load.balancer.RegionBalancer;
import org.apache.iotdb.confignode.manager.load.balancer.RouteBalancer;
import org.apache.iotdb.metrics.config.MetricConfigDescriptor;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Properties;

public class ConfigNodeDescriptor {
  private static final Logger LOGGER = LoggerFactory.getLogger(ConfigNodeDescriptor.class);

  private final CommonDescriptor commonDescriptor = CommonDescriptor.getInstance();

  private final ConfigNodeConfig conf = new ConfigNodeConfig();

  private ConfigNodeDescriptor() {
    loadProps();
  }

  public ConfigNodeConfig getConf() {
    return conf;
  }

  /**
   * get props url location
   *
   * @return url object if location exit, otherwise null.
   */
  public URL getPropsUrl() {
    // Check if a config-directory was specified first.
    String urlString = System.getProperty(ConfigNodeConstant.CONFIGNODE_CONF, null);
    // If it wasn't, check if a home directory was provided
    if (urlString == null) {
      urlString = System.getProperty(ConfigNodeConstant.CONFIGNODE_HOME, null);
      if (urlString != null) {
        urlString =
            urlString
                + File.separatorChar
                + "conf"
                + File.separatorChar
                + ConfigNodeConstant.CONF_FILE_NAME;
      } else {
        // When start ConfigNode with the script, the environment variables CONFIGNODE_CONF
        // and CONFIGNODE_HOME will be set. But we didn't set these two in developer mode.
        // Thus, just return null and use default Configuration in developer mode.
        return null;
      }
    }
    // If a config location was provided, but it doesn't end with a properties file,
    // append the default location.
    else if (!urlString.endsWith(".properties")) {
      urlString += (File.separatorChar + ConfigNodeConstant.CONF_FILE_NAME);
    }

    // If the url doesn't start with "file:" or "classpath:", it's provided as a no path.
    // So we need to add it to make it a real URL.
    if (!urlString.startsWith("file:") && !urlString.startsWith("classpath:")) {
      urlString = "file:" + urlString;
    }
    try {
      return new URL(urlString);
    } catch (MalformedURLException e) {
      return null;
    }
  }

  private void loadProps() {
    URL url = getPropsUrl();
    if (url == null) {
      LOGGER.warn(
          "Couldn't load the ConfigNode configuration from any of the known sources. Use default configuration.");
      return;
    }

    try (InputStream inputStream = url.openStream()) {

      LOGGER.info("start reading ConfigNode conf file: {}", url);

      Properties properties = new Properties();
      properties.load(inputStream);

      conf.setInternalAddress(
          properties.getProperty(IoTDBConstant.INTERNAL_ADDRESS, conf.getInternalAddress()));

      conf.setInternalPort(
          Integer.parseInt(
              properties.getProperty(
                  IoTDBConstant.INTERNAL_PORT, String.valueOf(conf.getInternalPort()))));

      conf.setConsensusPort(
          Integer.parseInt(
              properties.getProperty(
                  IoTDBConstant.CONSENSUS_PORT, String.valueOf(conf.getConsensusPort()))));

      // TODO: Enable multiple target_config_nodes
      String targetConfigNodes = properties.getProperty(IoTDBConstant.TARGET_CONFIG_NODES, null);
      if (targetConfigNodes != null) {
        conf.setTargetConfigNode(NodeUrlUtils.parseTEndPointUrl(targetConfigNodes));
      }

      conf.setSeriesPartitionSlotNum(
          Integer.parseInt(
              properties.getProperty(
                  "series_partition_slot_num", String.valueOf(conf.getSeriesPartitionSlotNum()))));

      conf.setSeriesPartitionExecutorClass(
          properties.getProperty(
              "series_partition_executor_class", conf.getSeriesPartitionExecutorClass()));

      conf.setConfigNodeConsensusProtocolClass(
          properties.getProperty(
              "config_node_consensus_protocol_class", conf.getConfigNodeConsensusProtocolClass()));

      conf.setSchemaRegionConsensusProtocolClass(
          properties.getProperty(
              "schema_region_consensus_protocol_class",
              conf.getSchemaRegionConsensusProtocolClass()));

      conf.setSchemaRegionPerDataNode(
          Double.parseDouble(
              properties.getProperty(
                  "schema_region_per_data_node",
                  String.valueOf(conf.getSchemaRegionPerDataNode()))));

      conf.setDataRegionConsensusProtocolClass(
          properties.getProperty(
              "data_region_consensus_protocol_class", conf.getDataRegionConsensusProtocolClass()));

      conf.setDataRegionPerProcessor(
          Double.parseDouble(
              properties.getProperty(
                  "data_region_per_processor", String.valueOf(conf.getDataRegionPerProcessor()))));

      try {
        conf.setRegionAllocateStrategy(
            RegionBalancer.RegionAllocateStrategy.valueOf(
                properties.getProperty(
                    "region_allocate_strategy", conf.getRegionAllocateStrategy().name())));
      } catch (IllegalArgumentException e) {
        LOGGER.warn(
            "The configured region allocate strategy does not exist, use the default: GREEDY!");
      }

      conf.setRpcAdvancedCompressionEnable(
          Boolean.parseBoolean(
              properties.getProperty(
                  "rpc_advanced_compression_enable",
                  String.valueOf(conf.isRpcAdvancedCompressionEnable()))));

      conf.setRpcMaxConcurrentClientNum(
          Integer.parseInt(
              properties.getProperty(
                  "rpc_max_concurrent_client_num",
                  String.valueOf(conf.getRpcMaxConcurrentClientNum()))));

      conf.setThriftDefaultBufferSize(
          Integer.parseInt(
              properties.getProperty(
                  "thrift_init_buffer_size", String.valueOf(conf.getThriftDefaultBufferSize()))));

      conf.setThriftMaxFrameSize(
          Integer.parseInt(
              properties.getProperty(
                  "thrift_max_frame_size", String.valueOf(conf.getThriftMaxFrameSize()))));

      conf.setSystemDir(properties.getProperty("system_dir", conf.getSystemDir()));

      conf.setConsensusDir(properties.getProperty("consensus_dir", conf.getConsensusDir()));

      conf.setUdfLibDir(properties.getProperty("udf_lib_dir", conf.getUdfLibDir()));

      conf.setTemporaryLibDir(
          properties.getProperty("temporary_lib_dir", conf.getTemporaryLibDir()));

      conf.setTimePartitionInterval(
          Long.parseLong(
              properties.getProperty(
                  "time_partition_interval_for_routing",
                  String.valueOf(conf.getTimePartitionInterval()))));

      conf.setSchemaReplicationFactor(
          Integer.parseInt(
              properties.getProperty(
                  "schema_replication_factor", String.valueOf(conf.getSchemaReplicationFactor()))));

      conf.setDataReplicationFactor(
          Integer.parseInt(
              properties.getProperty(
                  "data_replication_factor", String.valueOf(conf.getDataReplicationFactor()))));

      conf.setHeartbeatInterval(
          Long.parseLong(
              properties.getProperty(
                  "heartbeat_interval", String.valueOf(conf.getHeartbeatInterval()))));

      String routingPolicy = properties.getProperty("routing_policy", conf.getRoutingPolicy());
      if (routingPolicy.equals(RouteBalancer.GREEDY_POLICY)
          || routingPolicy.equals(RouteBalancer.LEADER_POLICY)) {
        conf.setRoutingPolicy(routingPolicy);
      } else {
        throw new IOException(
            String.format(
                "Unknown routing_policy: %s, please set to \"leader\" or \"greedy\"",
                routingPolicy));
      }

      String readConsistencyLevel =
          properties.getProperty("read_consistency_level", conf.getReadConsistencyLevel());
      if (readConsistencyLevel.equals("strong") || readConsistencyLevel.equals("weak")) {
        conf.setReadConsistencyLevel(readConsistencyLevel);
      } else {
        throw new IOException(
            String.format(
                "Unknown read_consistency_level: %s, please set to \"strong\" or \"weak\"",
                readConsistencyLevel));
      }

      // commons
      commonDescriptor.loadCommonProps(properties);
      commonDescriptor.initCommonConfigDir(conf.getSystemDir());

      conf.setProcedureCompletedEvictTTL(
          Integer.parseInt(
              properties.getProperty(
                  "procedure_completed_evict_ttl",
                  String.valueOf(conf.getProcedureCompletedEvictTTL()))));

      conf.setProcedureCompletedCleanInterval(
          Integer.parseInt(
              properties.getProperty(
                  "procedure_completed_clean_interval",
                  String.valueOf(conf.getProcedureCompletedCleanInterval()))));

      conf.setProcedureCoreWorkerThreadsSize(
          Integer.parseInt(
              properties.getProperty(
                  "procedure_core_worker_thread_size",
                  String.valueOf(conf.getProcedureCoreWorkerThreadsSize()))));

      loadRatisConsensusConfig(properties);
    } catch (IOException | BadNodeUrlException e) {
      LOGGER.warn("Couldn't load ConfigNode conf file, use default config", e);
    } finally {
      conf.updatePath();
      commonDescriptor
          .getConfig()
          .updatePath(System.getProperty(ConfigNodeConstant.CONFIGNODE_HOME, null));
      MetricConfigDescriptor.getInstance()
          .getMetricConfig()
          .updateRpcInstance(conf.getInternalAddress(), conf.getInternalPort());
    }
  }

  private void loadRatisConsensusConfig(Properties properties) {
    conf.setDataRegionRatisConsensusLogAppenderBufferSize(
        Long.parseLong(
            properties.getProperty(
                "data_region_ratis_log_appender_buffer_size_max",
                String.valueOf(conf.getDataRegionRatisConsensusLogAppenderBufferSize()))));

    conf.setPartitionRegionRatisConsensusLogAppenderBufferSize(
        Long.parseLong(
            properties.getProperty(
                "partition_region_ratis_log_appender_buffer_size_max",
                String.valueOf(conf.getPartitionRegionRatisConsensusLogAppenderBufferSize()))));

    conf.setSchemaRegionRatisConsensusLogAppenderBufferSize(
        Long.parseLong(
            properties.getProperty(
                "schema_region_ratis_log_appender_buffer_size_max",
                String.valueOf(conf.getSchemaRegionRatisConsensusLogAppenderBufferSize()))));

    conf.setDataRegionRatisSnapshotTriggerThreshold(
        Long.parseLong(
            properties.getProperty(
                "data_region_ratis_snapshot_trigger_threshold",
                String.valueOf(conf.getDataRegionRatisConsensusLogAppenderBufferSize()))));

    conf.setPartitionRegionRatisSnapshotTriggerThreshold(
        Long.parseLong(
            properties.getProperty(
                "partition_region_ratis_snapshot_trigger_threshold",
                String.valueOf(conf.getPartitionRegionRatisSnapshotTriggerThreshold()))));

    conf.setSchemaRegionRatisSnapshotTriggerThreshold(
        Long.parseLong(
            properties.getProperty(
                "schema_region_ratis_snapshot_trigger_threshold",
                String.valueOf(conf.getSchemaRegionRatisSnapshotTriggerThreshold()))));

    conf.setDataRegionRatisLogUnsafeFlushEnable(
        Boolean.parseBoolean(
            properties.getProperty(
                "data_region_ratis_log_unsafe_flush_enable",
                String.valueOf(conf.isDataRegionRatisLogUnsafeFlushEnable()))));

    conf.setPartitionRegionRatisLogUnsafeFlushEnable(
        Boolean.parseBoolean(
            properties.getProperty(
                "partition_region_ratis_log_unsafe_flush_enable",
                String.valueOf(conf.isPartitionRegionRatisLogUnsafeFlushEnable()))));

    conf.setSchemaRegionRatisLogUnsafeFlushEnable(
        Boolean.parseBoolean(
            properties.getProperty(
                "schema_region_ratis_log_unsafe_flush_enable",
                String.valueOf(conf.isSchemaRegionRatisLogUnsafeFlushEnable()))));

    conf.setDataRegionRatisLogSegmentSizeMax(
        Long.parseLong(
            properties.getProperty(
                "data_region_ratis_log_segment_size_max",
                String.valueOf(conf.getDataRegionRatisLogSegmentSizeMax()))));

    conf.setPartitionRegionRatisLogSegmentSizeMax(
        Long.parseLong(
            properties.getProperty(
                "partition_region_ratis_log_segment_size_max",
                String.valueOf(conf.getPartitionRegionRatisLogSegmentSizeMax()))));

    conf.setSchemaRegionRatisLogSegmentSizeMax(
        Long.parseLong(
            properties.getProperty(
                "schema_region_ratis_log_segment_size_max",
                String.valueOf(conf.getSchemaRegionRatisLogSegmentSizeMax()))));

    conf.setDataRegionRatisGrpcFlowControlWindow(
        Long.parseLong(
            properties.getProperty(
                "data_region_ratis_grpc_flow_control_window",
                String.valueOf(conf.getDataRegionRatisGrpcFlowControlWindow()))));

    conf.setPartitionRegionRatisGrpcFlowControlWindow(
        Long.parseLong(
            properties.getProperty(
                "partition_region_ratis_grpc_flow_control_window",
                String.valueOf(conf.getPartitionRegionRatisGrpcFlowControlWindow()))));

    conf.setSchemaRegionRatisGrpcFlowControlWindow(
        Long.parseLong(
            properties.getProperty(
                "schema_region_ratis_grpc_flow_control_window",
                String.valueOf(conf.getSchemaRegionRatisGrpcFlowControlWindow()))));

    conf.setDataRegionRatisRpcLeaderElectionTimeoutMinMs(
        Long.parseLong(
            properties.getProperty(
                "data_region_ratis_rpc_leader_election_timeout_min_ms",
                String.valueOf(conf.getDataRegionRatisRpcLeaderElectionTimeoutMinMs()))));

    conf.setPartitionRegionRatisRpcLeaderElectionTimeoutMinMs(
        Long.parseLong(
            properties.getProperty(
                "partition_region_ratis_rpc_leader_election_timeout_min_ms",
                String.valueOf(conf.getPartitionRegionRatisRpcLeaderElectionTimeoutMinMs()))));

    conf.setSchemaRegionRatisRpcLeaderElectionTimeoutMinMs(
        Long.parseLong(
            properties.getProperty(
                "schema_region_ratis_rpc_leader_election_timeout_min_ms",
                String.valueOf(conf.getSchemaRegionRatisRpcLeaderElectionTimeoutMinMs()))));

    conf.setDataRegionRatisRpcLeaderElectionTimeoutMinMs(
        Long.parseLong(
            properties.getProperty(
                "data_region_ratis_rpc_leader_election_timeout_max_ms",
                String.valueOf(conf.getDataRegionRatisRpcLeaderElectionTimeoutMaxMs()))));

    conf.setPartitionRegionRatisRpcLeaderElectionTimeoutMaxMs(
        Long.parseLong(
            properties.getProperty(
                "partition_region_ratis_rpc_leader_election_timeout_max_ms",
                String.valueOf(conf.getPartitionRegionRatisRpcLeaderElectionTimeoutMaxMs()))));

    conf.setSchemaRegionRatisRpcLeaderElectionTimeoutMaxMs(
        Long.parseLong(
            properties.getProperty(
                "schema_region_ratis_rpc_leader_election_timeout_max_ms",
                String.valueOf(conf.getSchemaRegionRatisRpcLeaderElectionTimeoutMaxMs()))));
  }

  /**
   * Check if the current ConfigNode is SeedConfigNode.
   *
   * @return True if the target_config_nodes points to itself
   */
  public boolean isSeedConfigNode() {
    return (conf.getInternalAddress().equals(conf.getTargetConfigNode().getIp())
            || (NodeUrlUtils.isLocalAddress(conf.getInternalAddress())
                && NodeUrlUtils.isLocalAddress(conf.getTargetConfigNode().getIp())))
        && conf.getInternalPort() == conf.getTargetConfigNode().getPort();
  }

  public static ConfigNodeDescriptor getInstance() {
    return ConfigNodeDescriptorHolder.INSTANCE;
  }

  private static class ConfigNodeDescriptorHolder {

    private static final ConfigNodeDescriptor INSTANCE = new ConfigNodeDescriptor();

    private ConfigNodeDescriptorHolder() {
      // empty constructor
    }
  }
}
