#pragma once

#include <Windows.h>

#include <atomic>
#include <memory>
#include <mutex>
#include <optional>

#include "adapters/windows/console/WindowsConsoleSession.h"
#include "adapters/windows/input/WindowsKeyInput.h"
#include "bootstrap/RuntimeHandles.h"

namespace ta::presentation
{
    class MenuController;
}

namespace ta::bootstrap
{
    class ApplicationRuntime;
    struct StartupError;

    class RuntimeHost final
    {
    public:
        explicit RuntimeHost(HMODULE dll_handle) noexcept;
        ~RuntimeHost() noexcept;

        RuntimeHost(const RuntimeHost&) = delete;
        RuntimeHost& operator=(const RuntimeHost&) = delete;

        [[nodiscard]] bool start() noexcept;
        void stop() noexcept;

    private:
        [[nodiscard]] bool fail_startup(const StartupError& error) noexcept;
        [[nodiscard]] bool shutdown_components(bool rollback) noexcept;

        HMODULE dll_handle_ = nullptr;
        ta::adapters::windows::console::WindowsConsoleSession console_;
        ta::adapters::windows::input::WindowsKeyInput key_input_;
        std::unique_ptr<ApplicationRuntime> application_;
        std::unique_ptr<ta::presentation::MenuController> menu_;
        std::optional<PresentHookHandle> present_hook_;
        std::optional<FeatureHooksHandle> feature_hooks_;
        std::mutex lifecycle_mutex_;
        std::atomic_bool shutdown_requested_{false};
    };
}
