/**
 * Copyright 2017 Google Inc.
 *
 * 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.
 */

#include "config.h"

#include "buildjson/buildjson.hpp"
#include "conf.hpp"
#include "dbus/dbusconfiguration.hpp"
#include "interfaces.hpp"
#include "pid/builder.hpp"
#include "pid/buildjson.hpp"
#include "pid/pidloop.hpp"
#include "pid/tuning.hpp"
#include "pid/zone.hpp"
#include "sensors/builder.hpp"
#include "sensors/buildjson.hpp"
#include "sensors/manager.hpp"
#include "util.hpp"

#include <CLI/CLI.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/signal_set.hpp>
#include <boost/asio/steady_timer.hpp>
#include <sdbusplus/asio/connection.hpp>
#include <sdbusplus/bus.hpp>
#include <sdbusplus/server/manager.hpp>

#include <chrono>
#include <filesystem>
#include <iostream>
#include <list>
#include <map>
#include <memory>
#include <thread>
#include <unordered_map>
#include <utility>
#include <vector>

namespace pid_control
{

/* The configuration converted sensor list. */
std::map<std::string, conf::SensorConfig> sensorConfig = {};
/* The configuration converted PID list. */
std::map<int64_t, conf::PIDConf> zoneConfig = {};
/* The configuration converted Zone configuration. */
std::map<int64_t, conf::ZoneConfig> zoneDetailsConfig = {};

namespace state
{
/* Set to true while canceling is in progress */
static bool isCanceling = false;
/* The zones build from configuration */
static std::unordered_map<int64_t, std::shared_ptr<ZoneInterface>> zones;
/* The timers used by the PID loop */
static std::vector<std::shared_ptr<boost::asio::steady_timer>> timers;
/* The sensors build from configuration */
static SensorManager mgmr;
} // namespace state

} // namespace pid_control

std::filesystem::path configPath = "";

/* async io context for operation */
boost::asio::io_context io;
/* async signal_set for signal handling */
boost::asio::signal_set signals(io, SIGHUP, SIGTERM);

/* buses for system control */
static sdbusplus::asio::connection modeControlBus(io);
static sdbusplus::asio::connection
    hostBus(io, sdbusplus::bus::new_system().release());
static sdbusplus::asio::connection
    passiveBus(io, sdbusplus::bus::new_system().release());

namespace pid_control
{

std::filesystem::path searchConfigurationPath()
{
    static constexpr auto name = "config.json";

    for (auto pathSeg : {std::filesystem::current_path(),
                         std::filesystem::path{"/var/lib/swampd"},
                         std::filesystem::path{"/usr/share/swampd"}})
    {
        auto file = pathSeg / name;
        if (std::filesystem::exists(file))
        {
            return file;
        }
    }

    return name;
}

void stopControlLoops()
{
    for (const auto& timer : state::timers)
    {
        timer->cancel();
    }
    state::isCanceling = true;
    state::timers.clear();

    if (state::zones.size() > 0 && state::zones.begin()->second.use_count() > 1)
    {
        throw std::runtime_error("wait for count back to 1");
    }

    state::zones.clear();
    state::isCanceling = false;
}

void restartControlLoops()
{
    stopControlLoops();

    const std::filesystem::path path =
        (!configPath.empty()) ? configPath : searchConfigurationPath();

    if (std::filesystem::exists(path))
    {
        /*
         * When building the sensors, if any of the dbus passive ones aren't on
         * the bus, it'll fail immediately.
         */
        try
        {
            auto jsonData = parseValidateJson(path);
            sensorConfig = buildSensorsFromJson(jsonData);
            std::tie(zoneConfig,
                     zoneDetailsConfig) = buildPIDsFromJson(jsonData);
        }
        catch (const std::exception& e)
        {
            std::cerr << "Failed during building: " << e.what() << "\n";
            exit(EXIT_FAILURE); /* fatal error. */
        }
    }
    else
    {
        static boost::asio::steady_timer reloadTimer(io);
        if (!dbus_configuration::init(modeControlBus, reloadTimer, sensorConfig,
                                      zoneConfig, zoneDetailsConfig))
        {
            return; // configuration not ready
        }
    }

    state::mgmr = buildSensors(sensorConfig, passiveBus, hostBus);
    state::zones = buildZones(zoneConfig, zoneDetailsConfig, state::mgmr,
                              modeControlBus);

    if (0 == state::zones.size())
    {
        std::cerr << "No zones defined, exiting.\n";
        std::exit(EXIT_FAILURE);
    }

    for (const auto& i : state::zones)
    {
        std::shared_ptr<boost::asio::steady_timer> timer =
            state::timers.emplace_back(
                std::make_shared<boost::asio::steady_timer>(io));
        std::cerr << "pushing zone " << i.first << "\n";
        pidControlLoop(i.second, timer, &state::isCanceling);
    }
}

void tryRestartControlLoops(bool first)
{
    static const auto delayTime = std::chrono::seconds(10);
    static boost::asio::steady_timer timer(io);

    auto restartLbd = [](const boost::system::error_code& error) {
        if (error == boost::asio::error::operation_aborted)
        {
            return;
        }

        // retry when restartControlLoops() has some failure.
        try
        {
            restartControlLoops();
        }
        catch (const std::exception& e)
        {
            std::cerr << "Failed during restartControlLoops, try again: "
                      << e.what() << "\n";
            tryRestartControlLoops(false);
        }
    };

    // first time of trying to restart the control loop without a delay
    if (first)
    {
        boost::asio::post(io,
                          std::bind(restartLbd, boost::system::error_code()));
    }
    // re-try control loop, set up a delay.
    else
    {
        timer.expires_after(delayTime);
        timer.async_wait(restartLbd);
    }

    return;
}

void tryTerminateControlLoops(bool first)
{
    static const auto delayTime = std::chrono::milliseconds(50);
    static boost::asio::steady_timer timer(io);

    auto stopLbd = [](const boost::system::error_code& error) {
        if (error == boost::asio::error::operation_aborted)
        {
            return;
        }

        // retry when stopControlLoops() has some failure.
        try
        {
            stopControlLoops();
        }
        catch (const std::exception& e)
        {
            std::cerr << "Failed during stopControlLoops, try again: "
                      << e.what() << "\n";
            tryTerminateControlLoops(false);
            return;
        }
        io.stop();
    };

    // first time of trying to stop the control loop without a delay
    if (first)
    {
        boost::asio::post(io, std::bind(stopLbd, boost::system::error_code()));
    }
    // re-try control loop, set up a delay.
    else
    {
        timer.expires_after(delayTime);
        timer.async_wait(stopLbd);
    }

    return;
}

} // namespace pid_control

void signalHandler(const boost::system::error_code& error, int signal_number)
{
    static boost::asio::steady_timer timer(io);

    if (error)
    {
        std::cout << "Signal " << signal_number
                  << " handler error: " << error.message() << "\n";
        return;
    }
    if (signal_number == SIGTERM)
    {
        pid_control::tryTerminateControlLoops(true);
    }
    else
    {
        timer.expires_after(std::chrono::seconds(1));
        timer.async_wait([](const boost::system::error_code ec) {
            if (ec)
            {
                std::cout << "Signal timer error: " << ec.message() << "\n";
                return;
            }

            std::cout << "reloading configuration\n";
            pid_control::tryRestartControlLoops();
        });
    }

    signals.async_wait(signalHandler);
}

int main(int argc, char* argv[])
{
    loggingPath = "";
    loggingEnabled = false;
    tuningEnabled = false;
    debugEnabled = false;
    coreLoggingEnabled = false;

    CLI::App app{"OpenBMC Fan Control Daemon"};

    app.add_option("-c,--conf", configPath,
                   "Optional parameter to specify configuration at run-time")
        ->check(CLI::ExistingFile);
    app.add_option("-l,--log", loggingPath,
                   "Optional parameter to specify logging folder")
        ->check(CLI::ExistingDirectory);
    app.add_flag("-t,--tuning", tuningEnabled, "Enable or disable tuning");
    app.add_flag("-d,--debug", debugEnabled, "Enable or disable debug mode");
    app.add_flag("-g,--corelogging", coreLoggingEnabled,
                 "Enable or disable logging of core PID loop computations");

    CLI11_PARSE(app, argc, argv);

    static constexpr auto loggingEnablePath = "/etc/thermal.d/logging";
    static constexpr auto tuningEnablePath = "/etc/thermal.d/tuning";
    static constexpr auto debugEnablePath = "/etc/thermal.d/debugging";
    static constexpr auto coreLoggingEnablePath = "/etc/thermal.d/corelogging";

    // Set up default logging path, preferring command line if it was given
    std::string defLoggingPath(loggingPath);
    if (defLoggingPath.empty())
    {
        defLoggingPath = std::filesystem::temp_directory_path();
    }
    else
    {
        // Enable logging, if user explicitly gave path on command line
        loggingEnabled = true;
    }

    // If this file exists, enable logging at runtime
    std::ifstream fsLogging(loggingEnablePath);
    if (fsLogging)
    {
        // Allow logging path to be changed by file content
        std::string altPath;
        std::getline(fsLogging, altPath);
        fsLogging.close();

        if (std::filesystem::exists(altPath))
        {
            loggingPath = altPath;
        }
        else
        {
            loggingPath = defLoggingPath;
        }

        loggingEnabled = true;
    }
    if (loggingEnabled)
    {
        std::cerr << "Logging enabled: " << loggingPath << "\n";
    }

    // If this file exists, enable tuning at runtime
    if (std::filesystem::exists(tuningEnablePath))
    {
        tuningEnabled = true;
    }
    if (tuningEnabled)
    {
        std::cerr << "Tuning enabled\n";
    }

    // If this file exists, enable debug mode at runtime
    if (std::filesystem::exists(debugEnablePath))
    {
        debugEnabled = true;
    }

    if (debugEnabled)
    {
        std::cerr << "Debug mode enabled\n";
    }

    // If this file exists, enable core logging at runtime
    if (std::filesystem::exists(coreLoggingEnablePath))
    {
        coreLoggingEnabled = true;
    }
    if (coreLoggingEnabled)
    {
        std::cerr << "Core logging enabled\n";
    }

    static constexpr auto modeRoot = "/xyz/openbmc_project/settings/fanctrl";
    // Create a manager for the ModeBus because we own it.
    sdbusplus::server::manager_t(static_cast<sdbusplus::bus_t&>(modeControlBus),
                                 modeRoot);
    hostBus.request_name("xyz.openbmc_project.Hwmon.external");
    modeControlBus.request_name("xyz.openbmc_project.State.FanCtrl");
    sdbusplus::server::manager_t objManager(modeControlBus, modeRoot);

    // Enable SIGHUP handling to reload JSON config
    signals.async_wait(signalHandler);

    /*
     * All sensors are managed by one manager, but each zone has a pointer to
     * it.
     */

    pid_control::tryRestartControlLoops();

    io.run();
    return 0;
}
