/*
 * SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed 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 _NIXL_PARAMS_H
#define _NIXL_PARAMS_H

#include <string>
#include <cstdint>
#include "nixl_types.h"

/**
 * @class nixlAgentConfig
 * @brief Per Agent configuration information, such as if progress thread should be used.
 *        Other configs such as assigned IP/port or device access can be added.
 */
class nixlAgentConfig {
    private:

        /** @var Enable progress thread */
        bool     useProgThread;
        /** @var Enable listener thread */
        bool     useListenThread;
        /** @var Port for listener thread to use */
        int      listenPort;
        /** @var synchronization mode for multi-threaded environment execution */
        nixl_thread_sync_t syncMode;
        /** @var Capture telemetry info regardless of environment variables*/
        bool captureTelemetry;

    public:

        /**
         * @var Progress thread event waiting timeout.
         *      Defines a delay between periodic main loop iterations that progress every worker
         *      unconditionally of any pending event signals.
         */
        uint64_t pthrDelay;
        /**
         * @var Listener thread frequency knob (in us)
         *      Listener thread sleeps in a similar way to progress thread, desrcibed previously.
         *      These will be combined into a unified NIXL Thread API in a future version.
         */
        uint64_t lthrDelay;

        /**
         * @var ETCD watch timeout in microseconds
         *      Timeout for waiting for metadata changes when watching etcd keys.
         */
        std::chrono::microseconds etcdWatchTimeout;

        /**
         * @brief  Agent configuration constructor for enabling various features.
         * @param use_prog_thread    flag to determine use of progress thread
         * @param use_listen_thread  Optional flag to determine use of listener thread
         * @param port               Optional port for listener thread to listen on
         * @param sync_mode          Optional Thread synchronization mode
         * @param num_workers        Optional number of shared workers per backend
         * @param pthr_delay_us      Optional delay for pthread in us
         * @param lthr_delay_us      Optional delay for listener thread in us
         * @param capture_telemetry  Optional flag to enable telemetry capture
         * @param etcd_watch_timeout Optional timeout for etcd watch operations in microseconds
         */
        nixlAgentConfig(const bool use_prog_thread,
                        const bool use_listen_thread = false,
                        const int port = 0,
                        nixl_thread_sync_t sync_mode = nixl_thread_sync_t::NIXL_THREAD_SYNC_DEFAULT,
                        unsigned int num_workers = 1,
                        const uint64_t pthr_delay_us = 0,
                        const uint64_t lthr_delay_us = 100000,
                        const bool capture_telemetry = false,
                        const std::chrono::microseconds &etcd_watch_timeout =
                            std::chrono::microseconds(5000000))
            : useProgThread(use_prog_thread),
              useListenThread(use_listen_thread),
              listenPort(port),
              syncMode(sync_mode),
              captureTelemetry(capture_telemetry),
              pthrDelay(pthr_delay_us),
              lthrDelay(lthr_delay_us),
              etcdWatchTimeout(etcd_watch_timeout) {}

        /**
         * @brief Copy constructor for nixlAgentConfig object
         *
         * @param cfg  nixlAgentConfig object
         */
        nixlAgentConfig (const nixlAgentConfig &cfg) = default;

        /**
         * @brief Default destructor for nixlAgentConfig
         */
        ~nixlAgentConfig () = default;

    friend class nixlAgent;
    friend class nixlAgentData;
};

#endif
