#pragma once

#include <softbus_api/ExecuteCommand.h>
#include <softbus_bus/Bus.h>
#include <softbus_command/CommandContext.h>
#include <softbus_registry/PointRegistry.h>

#include <chrono>
#include <condition_variable>
#include <mutex>
#include <optional>
#include <string>
#include <unordered_map>

namespace softbus::command {

class CommandService {
public:
    explicit CommandService(softbus::registry::PointRegistry* registry,
                            std::chrono::milliseconds timeout = std::chrono::milliseconds(5000));

    void attachBus(softbus::bus::Bus* bus);
    CommandContext submit(const softbus::api::ExecuteCommand& command, bool waitForAck = true);
    std::optional<CommandContext> findByRequestId(const std::string& requestId) const;

private:
    void handleAck(const softbus::bus::BusMessage& message);
    std::string generateRequestId() const;

    softbus::registry::PointRegistry* registry_{nullptr};
    softbus::bus::Bus* bus_{nullptr};
    softbus::bus::Bus::SubscriptionId ackSub_{0};
    std::chrono::milliseconds timeout_;
    mutable std::mutex mutex_;
    std::unordered_map<std::string, CommandContext> contexts_;
    std::condition_variable ackCv_;
};

} // namespace softbus::command
