/*
 *  Copyright (C) 2004-2023 Savoir-faire Linux Inc.
 *
 *  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, see <https://www.gnu.org/licenses/>.
 */
#include "threadloop.h"

#include <ciso646> // fix windows compiler bug

namespace dhtnet {

void
ThreadLoop::mainloop(std::thread::id& tid,
                     const std::function<bool()> setup,
                     const std::function<void()> process,
                     const std::function<void()> cleanup)
{
    tid = std::this_thread::get_id();
    try {
        if (setup()) {
            while (state_ == ThreadState::RUNNING)
                process();
            cleanup();
        } else {
            throw std::runtime_error("setup failed");
        }
    } catch (const ThreadLoopException& e) {
        if (logger_) logger_->e("[threadloop:{}] ThreadLoopException: {}", fmt::ptr(this), e.what());
    } catch (const std::exception& e) {
        if (logger_) logger_->e("[threadloop:{}] Unwaited exception: {}", fmt::ptr(this), e.what());
    }
    stop();
}

ThreadLoop::ThreadLoop(std::shared_ptr<dht::log::Logger> logger,
                       const std::function<bool()>& setup,
                       const std::function<void()>& process,
                       const std::function<void()>& cleanup)
    : setup_(setup)
    , process_(process)
    , cleanup_(cleanup)
    , thread_()
    , logger_(std::move(logger))
{}

ThreadLoop::~ThreadLoop()
{
    if (isRunning()) {
        if (logger_) logger_->error("join() should be explicitly called in owner's destructor");
        join();
    }
}

void
ThreadLoop::start()
{
    const auto s = state_.load();

    if (s == ThreadState::RUNNING) {
        if (logger_) logger_->error("already started");
        return;
    }

    // stop pending but not processed by thread yet?
    if (s == ThreadState::STOPPING and thread_.joinable()) {
        if (logger_) logger_->debug("stop pending");
        thread_.join();
    }

    state_ = ThreadState::RUNNING;
    thread_ = std::thread(&ThreadLoop::mainloop, this, std::ref(threadId_), setup_, process_, cleanup_);
    threadId_ = thread_.get_id();
}

void
ThreadLoop::stop()
{
    if (state_ == ThreadState::RUNNING)
        state_ = ThreadState::STOPPING;
}

void
ThreadLoop::join()
{
    stop();
    if (thread_.joinable())
        thread_.join();
}

void
ThreadLoop::waitForCompletion()
{
    if (thread_.joinable())
        thread_.join();
}

void
ThreadLoop::exit()
{
    stop();
    throw ThreadLoopException();
}

bool
ThreadLoop::isRunning() const noexcept
{
#ifdef _WIN32
    return state_ == ThreadState::RUNNING;
#else
    return thread_.joinable() and state_ == ThreadState::RUNNING;
#endif
}

void
InterruptedThreadLoop::stop()
{
    ThreadLoop::stop();
    cv_.notify_one();
}
} // namespace dhtnet
