/**
* 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.
 */
#include "NodesSupplier.h"
#include "RpcCommon.h"
#include "Session.h"
#include "SessionDataSet.h"
#include <algorithm>
#include <iostream>
#include <utility>

const std::string NodesSupplier::SHOW_AVAILABLE_URLS_COMMAND = "SHOW AVAILABLE URLS";
const std::string NodesSupplier::RUNNING_STATUS = "Running";
const std::string NodesSupplier::STATUS_COLUMN_NAME = "Status";
const std::string NodesSupplier::IP_COLUMN_NAME = "RpcAddress";
const std::string NodesSupplier::PORT_COLUMN_NAME = "RpcPort";
const std::string NodesSupplier::REMOVING_STATUS = "Removing";

const int64_t NodesSupplier::TIMEOUT_IN_MS = 60000;
const int NodesSupplier::THRIFT_DEFAULT_BUFFER_SIZE = 4096;
const int NodesSupplier::THRIFT_MAX_FRAME_SIZE = 1048576;
const int NodesSupplier::CONNECTION_TIMEOUT_IN_MS = 1000;

TEndPoint RoundRobinPolicy::select(const std::vector<TEndPoint>& nodes) {
  static std::atomic_uint index{0};

  if (nodes.empty()) {
    throw IoTDBException("No available nodes");
  }

  return nodes[index++ % nodes.size()];
}

StaticNodesSupplier::StaticNodesSupplier(const std::vector<TEndPoint>& nodes,
                                         NodeSelectionPolicy policy)
    : availableNodes_(nodes), policy_(std::move(policy)) {}

Optional<TEndPoint> StaticNodesSupplier::getQueryEndPoint() {
  try {
    if (availableNodes_.empty()) {
      return Optional<TEndPoint>::none();
    }
    return policy_(availableNodes_);
  } catch (const IoTDBException& e) {
    return Optional<TEndPoint>::none();
  }
}

std::vector<TEndPoint> StaticNodesSupplier::getEndPointList() {
  return availableNodes_;
}

StaticNodesSupplier::~StaticNodesSupplier() = default;

std::shared_ptr<NodesSupplier> NodesSupplier::create(
    const std::vector<TEndPoint>& endpoints, const std::string& userName,
    const std::string& password, bool useSSL, const std::string& trustCertFilePath,
    const std::string& zoneId, int32_t thriftDefaultBufferSize, int32_t thriftMaxFrameSize,
    int32_t connectionTimeoutInMs, bool enableRPCCompression, const std::string& version,
    std::chrono::milliseconds refreshInterval, NodeSelectionPolicy policy) {
  if (endpoints.empty()) {
    return nullptr;
  }
  auto supplier = std::make_shared<NodesSupplier>(
      userName, password, useSSL, trustCertFilePath, zoneId, thriftDefaultBufferSize,
      thriftMaxFrameSize, connectionTimeoutInMs, enableRPCCompression, version, endpoints, policy);
  supplier->startBackgroundRefresh(refreshInterval);
  return supplier;
}

NodesSupplier::NodesSupplier(const std::string& userName, const std::string& password, bool useSSL,
                             const std::string& trustCertFilePath, const std::string& zoneId,
                             int32_t thriftDefaultBufferSize, int32_t thriftMaxFrameSize,
                             int32_t connectionTimeoutInMs, bool enableRPCCompression,
                             const std::string& version, const std::vector<TEndPoint>& endpoints,
                             NodeSelectionPolicy policy)
    : userName_(userName), password_(password), zoneId_(zoneId),
      thriftDefaultBufferSize_(thriftDefaultBufferSize), thriftMaxFrameSize_(thriftMaxFrameSize),
      connectionTimeoutInMs_(connectionTimeoutInMs), useSSL_(useSSL),
      trustCertFilePath_(trustCertFilePath), enableRPCCompression_(enableRPCCompression),
      version_(version), endpoints_(endpoints), selectionPolicy_(policy) {
  deduplicateEndpoints();
}

std::vector<TEndPoint> NodesSupplier::getEndPointList() {
  std::lock_guard<std::mutex> lock(mutex_);
  return endpoints_;
}

TEndPoint NodesSupplier::selectQueryEndpoint() {
  std::lock_guard<std::mutex> lock(mutex_);
  try {
    return selectionPolicy_(endpoints_);
  } catch (const std::exception& e) {
    log_error("NodesSupplier::selectQueryEndpoint exception: %s", e.what());
    throw IoTDBException("NodesSupplier::selectQueryEndpoint exception, " + std::string(e.what()));
  }
}

Optional<TEndPoint> NodesSupplier::getQueryEndPoint() {
  try {
    return selectQueryEndpoint();
  } catch (const IoTDBException& e) {
    return Optional<TEndPoint>::none();
  }
}

NodesSupplier::~NodesSupplier() {
  stopBackgroundRefresh();
  if (client_ != nullptr) {
    client_->close();
  }
}

void NodesSupplier::deduplicateEndpoints() {
  std::vector<TEndPoint> uniqueEndpoints;
  uniqueEndpoints.reserve(endpoints_.size());
  for (const auto& endpoint : endpoints_) {
    if (std::find(uniqueEndpoints.begin(), uniqueEndpoints.end(), endpoint) ==
        uniqueEndpoints.end()) {
      uniqueEndpoints.push_back(endpoint);
    }
  }
  endpoints_ = std::move(uniqueEndpoints);
}

void NodesSupplier::startBackgroundRefresh(std::chrono::milliseconds interval) {
  isRunning_ = true;
  refreshEndpointList();
  refreshThread_ = std::thread([this, interval] {
    while (isRunning_) {
      refreshEndpointList();
      std::unique_lock<std::mutex> cvLock(this->mutex_);
      refreshCondition_.wait_for(cvLock, interval, [this]() { return !isRunning_.load(); });
    }
  });
}

std::vector<TEndPoint> NodesSupplier::fetchLatestEndpoints() {
  for (const auto& endpoint : endpoints_) {
    try {
      if (client_ == nullptr) {
        client_ = std::make_shared<ThriftConnection>(endpoint);
        client_->init(userName_, password_, enableRPCCompression_, useSSL_, trustCertFilePath_,
                      zoneId_, version_);
      }

      auto sessionDataSet = client_->executeQueryStatement(SHOW_AVAILABLE_URLS_COMMAND);

      uint32_t columnAddrIdx = -1, columnPortIdx = -1;
      auto columnNames = sessionDataSet->getColumnNames();
      for (uint32_t i = 0; i < columnNames.size(); i++) {
        if (columnNames[i] == IP_COLUMN_NAME) {
          columnAddrIdx = i;
        } else if (columnNames[i] == PORT_COLUMN_NAME) {
          columnPortIdx = i;
        }
      }

      if (columnAddrIdx == -1 || columnPortIdx == -1) {
        throw IoTDBException("Required columns not found in query result.");
      }

      std::vector<TEndPoint> ret;
      while (sessionDataSet->hasNext()) {
        auto record = sessionDataSet->next();
        std::string ip;
        int32_t port = 0;

        if (record->fields.at(columnAddrIdx).stringV.is_initialized()) {
          ip = record->fields.at(columnAddrIdx).stringV.value();
        }
        if (record->fields.at(columnPortIdx).intV.is_initialized()) {
          port = record->fields.at(columnPortIdx).intV.value();
        }

        if (UrlUtils::isWildcardAddress(ip)) {
          log_warn("Skipping invalid node: " + ip + ":" + std::to_string(port));
          continue;
        }
        TEndPoint newEndpoint;
        newEndpoint.ip = ip;
        newEndpoint.port = port;
        ret.emplace_back(newEndpoint);
      }
      return ret; // success
    } catch (const std::exception& e) {
      log_warn("Failed to fetch endpoints from " + endpoint.ip + ":" +
               std::to_string(endpoint.port) + " , error=" + e.what());
      client_.reset(); // reset client before retrying next endpoint
      continue;        // try next endpoint
    }
  }
  throw IoTDBException("NodesSupplier::fetchLatestEndpoints failed: all nodes unreachable.");
}

void NodesSupplier::refreshEndpointList() {
  try {
    auto newEndpoints = fetchLatestEndpoints();
    if (newEndpoints.empty()) {
      return;
    }

    std::lock_guard<std::mutex> lock(mutex_);
    endpoints_.swap(newEndpoints);
    deduplicateEndpoints();
  } catch (const IoTDBException& e) {
    log_error(std::string("NodesSupplier::refreshEndpointList failed: ") + e.what());
  }
}

void NodesSupplier::stopBackgroundRefresh() noexcept {
  if (isRunning_.exchange(false)) {
    refreshCondition_.notify_all();
    if (refreshThread_.joinable()) {
      refreshThread_.join();
    }
  }
}
