/*
 *  Copyright (C) 2004-2023 Savoir-faire Linux Inc.
 *
 *  Author: Guillaume Roguez <Guillaume.Roguez@savoirfairelinux.com>
 *  Author: Eloi Bail <Eloi.Bail@savoirfairelinux.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
 */

#pragma once

#include <atomic>
#include <thread>
#include <functional>
#include <stdexcept>
#include <condition_variable>
#include <mutex>

#include <opendht/logger.h>

namespace dhtnet {

struct ThreadLoopException : public std::runtime_error
{
    ThreadLoopException()
        : std::runtime_error("ThreadLoopException")
    {}
};

class ThreadLoop
{
public:
    enum class ThreadState { READY, RUNNING, STOPPING };

    ThreadLoop(std::shared_ptr<dht::log::Logger> logger,
               const std::function<bool()>& setup,
               const std::function<void()>& process,
               const std::function<void()>& cleanup);
    virtual ~ThreadLoop();

    void start();
    void exit();
    virtual void stop();
    void join();
    void waitForCompletion(); // thread will stop itself

    bool isRunning() const noexcept;
    bool isStopping() const noexcept { return state_ == ThreadState::STOPPING; }
    std::thread::id get_id() const noexcept { return threadId_; }

private:
    ThreadLoop(const ThreadLoop&) = delete;
    ThreadLoop(ThreadLoop&&) noexcept = delete;
    ThreadLoop& operator=(const ThreadLoop&) = delete;
    ThreadLoop& operator=(ThreadLoop&&) noexcept = delete;

    // These must be provided by users of ThreadLoop
    std::function<bool()> setup_;
    std::function<void()> process_;
    std::function<void()> cleanup_;

    void mainloop(std::thread::id& tid,
                  const std::function<bool()> setup,
                  const std::function<void()> process,
                  const std::function<void()> cleanup);

    std::atomic<ThreadState> state_ {ThreadState::READY};
    std::thread::id threadId_;
    std::thread thread_;
    std::shared_ptr<dht::log::Logger> logger_;
};

class InterruptedThreadLoop : public ThreadLoop
{
public:
    InterruptedThreadLoop(std::shared_ptr<dht::log::Logger> logger,
                          const std::function<bool()>& setup,
                          const std::function<void()>& process,
                          const std::function<void()>& cleanup)
        : ThreadLoop::ThreadLoop(logger, setup, process, cleanup)
    {}

    void stop() override;

    void interrupt() noexcept { cv_.notify_one(); }

    template<typename Rep, typename Period>
    void wait_for(const std::chrono::duration<Rep, Period>& rel_time)
    {
        if (std::this_thread::get_id() != get_id())
            throw std::runtime_error("can not call wait_for outside thread context");

        std::unique_lock<std::mutex> lk(mutex_);
        cv_.wait_for(lk, rel_time, [this]() { return isStopping(); });
    }

    template<typename Rep, typename Period, typename Pred>
    bool wait_for(const std::chrono::duration<Rep, Period>& rel_time, Pred&& pred)
    {
        if (std::this_thread::get_id() != get_id())
            throw std::runtime_error("can not call wait_for outside thread context");

        std::unique_lock<std::mutex> lk(mutex_);
        return cv_.wait_for(lk, rel_time, [this, pred] { return isStopping() || pred(); });
    }

    template<typename Pred>
    void wait(Pred&& pred)
    {
        if (std::this_thread::get_id() != get_id())
            throw std::runtime_error("Can not call wait outside thread context");

        std::unique_lock<std::mutex> lk(mutex_);
        cv_.wait(lk, [this, p = std::forward<Pred>(pred)] { return isStopping() || p(); });
    }

private:
    std::mutex mutex_;
    std::condition_variable cv_;
};

} // namespace jami
