/**
 * 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.
 */
#ifndef IOTDB_NODES_SUPPLIER_H
#define IOTDB_NODES_SUPPLIER_H

#include <vector>
#include <atomic>
#include <boost/optional.hpp>
#include <mutex>
#include <chrono>
#include <thread>
#include <functional>
#include <condition_variable>
#include <algorithm>

#include "ThriftConnection.h"

class TEndPoint;

class RoundRobinPolicy {
public:
    static TEndPoint select(const std::vector<TEndPoint>& nodes);
};

class INodesSupplier {
public:
    virtual ~INodesSupplier() = default;
    virtual boost::optional<TEndPoint> getQueryEndPoint() = 0;
    virtual std::vector<TEndPoint> getEndPointList() = 0;
    using NodeSelectionPolicy = std::function<TEndPoint(const std::vector<TEndPoint>&)>;
};

class StaticNodesSupplier : public INodesSupplier {
public:
    explicit StaticNodesSupplier(const std::vector<TEndPoint>& nodes, 
                                NodeSelectionPolicy policy = RoundRobinPolicy::select);

    boost::optional<TEndPoint> getQueryEndPoint() override;

    std::vector<TEndPoint> getEndPointList() override;

    ~StaticNodesSupplier() override;

private:
    const std::vector<TEndPoint> availableNodes_;
    NodeSelectionPolicy policy_;
};

class NodesSupplier : public INodesSupplier {
public:
    static const std::string SHOW_AVAILABLE_URLS_COMMAND;
    static const std::string RUNNING_STATUS;
    static const std::string STATUS_COLUMN_NAME;
    static const std::string IP_COLUMN_NAME;
    static const std::string PORT_COLUMN_NAME;
    static const std::string REMOVING_STATUS;

    static const int64_t TIMEOUT_IN_MS;
    static const int FETCH_SIZE;
    static const int THRIFT_DEFAULT_BUFFER_SIZE;
    static const int THRIFT_MAX_FRAME_SIZE;
    static const int CONNECTION_TIMEOUT_IN_MS;

    static std::shared_ptr<NodesSupplier> create(
        const std::vector<TEndPoint>& endpoints,
        const std::string& userName,
        const std::string& password,
        bool useSSL = false,
        const std::string& trustCertFilePath = "",
        const std::string& zoneId = "",
        int32_t thriftDefaultBufferSize = ThriftConnection::THRIFT_DEFAULT_BUFFER_SIZE,
        int32_t thriftMaxFrameSize = ThriftConnection::THRIFT_MAX_FRAME_SIZE,
        int32_t connectionTimeoutInMs = ThriftConnection::CONNECTION_TIMEOUT_IN_MS,
        bool enableRPCCompression = false,
        const std::string& version = "V_1_0",
        std::chrono::milliseconds refreshInterval = std::chrono::milliseconds(TIMEOUT_IN_MS),
        NodeSelectionPolicy policy = RoundRobinPolicy::select
    );

    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
    );

    std::vector<TEndPoint> getEndPointList() override;

    boost::optional<TEndPoint> getQueryEndPoint() override;

    ~NodesSupplier() override;

private:
    std::string userName_;
    std::string password_;
    int32_t thriftDefaultBufferSize_;
    int32_t thriftMaxFrameSize_;
    int32_t connectionTimeoutInMs_;
    bool useSSL_;
    std::string trustCertFilePath_;
    bool enableRPCCompression_;
    std::string version_;
    std::string zoneId_;

    std::mutex mutex_;
    std::vector<TEndPoint> endpoints_;
    NodeSelectionPolicy selectionPolicy_;

    std::atomic<bool> isRunning_{false};
    std::thread refreshThread_;
    std::condition_variable refreshCondition_;

    std::shared_ptr<ThriftConnection> client_;

    void deduplicateEndpoints();

    void startBackgroundRefresh(std::chrono::milliseconds interval);

    std::vector<TEndPoint> fetchLatestEndpoints();

    void refreshEndpointList();

    TEndPoint selectQueryEndpoint();

    void stopBackgroundRefresh() noexcept;
};

#endif