/**
 * Copyright © 2022 IBM Corporation
 *
 * 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"

#ifndef CONTROL_USE_JSON
#include "manager.hpp"

#include <CLI/CLI.hpp>
#else
#include "../utils/flight_recorder.hpp"
#include "json/manager.hpp"
#endif

#include "dbus_paths.hpp"
#include "sdbusplus.hpp"
#include "sdeventplus.hpp"

#include <phosphor-logging/log.hpp>
#include <sdbusplus/bus.hpp>
#include <sdeventplus/event.hpp>
#include <sdeventplus/source/signal.hpp>
#include <stdplus/signal.hpp>

#include <fstream>

using namespace phosphor::fan::control;
using namespace phosphor::logging;

#ifdef CONTROL_USE_JSON
void dumpFlightRecorder()
{
    nlohmann::json data;
    phosphor::fan::control::json::FlightRecorder::instance().dump(data);
    std::ofstream file{json::Manager::dumpFile};
    file << std::setw(4) << data;
}
#endif

int main([[maybe_unused]] int argc, [[maybe_unused]] char* argv[])
{
    auto event = phosphor::fan::util::SDEventPlus::getEvent();

#ifndef CONTROL_USE_JSON
    CLI::App app{"Phosphor Fan Control"};

    bool init = false;
    bool control = false;
    app.add_flag("-i,--init", init, "Sets fans to full speed, delays, exits");
    app.add_flag("-c,--control", control, "Start fan control algorithm");
    app.require_option();

    try
    {
        app.parse(argc, argv);
    }
    catch (const CLI::Error& e)
    {
        return app.exit(e);
    }

    Mode mode;
    if (init)
    {
        mode = Mode::init;
    }
    else if (control)
    {
        mode = Mode::control;
    }
#endif

    // Attach the event object to the bus object so we can
    // handle both sd_events (for the timers) and dbus signals.
    phosphor::fan::util::SDBusPlus::getBus().attach_event(
        event.get(), SD_EVENT_PRIORITY_NORMAL);

    try
    {
#ifdef CONTROL_USE_JSON
        phosphor::fan::control::json::FlightRecorder::instance().log("main",
                                                                     "Startup");
        json::Manager manager(event);

        // Handle loading fan control's config file(s)
        phosphor::fan::JsonConfig config(
            std::bind(&json::Manager::load, &manager));

        // Enable SIGHUP handling to reload JSON configs
        stdplus::signal::block(SIGHUP);
        sdeventplus::source::Signal signal(
            event, SIGHUP,
            std::bind(&json::Manager::sighupHandler, &manager,
                      std::placeholders::_1, std::placeholders::_2));

        // Enable SIGUSR1 handling to dump the flight recorder
        stdplus::signal::block(SIGUSR1);
        sdeventplus::source::Signal sigUsr1(
            event, SIGUSR1,
            std::bind(&json::Manager::dumpDebugData, &manager,
                      std::placeholders::_1, std::placeholders::_2));

        phosphor::fan::util::SDBusPlus::getBus().request_name(CONTROL_BUSNAME);
#else
        Manager manager(phosphor::fan::util::SDBusPlus::getBus(), event, mode);

        // Init mode will just set fans to max and delay
        if (mode == Mode::init)
        {
            manager.doInit(event);
            return 0;
        }
#endif
        return event.loop();
    }
    // Log the useful metadata on these exceptions and let the app
    // return 1 so it is restarted without a core dump.
    catch (const phosphor::fan::util::DBusServiceError& e)
    {
        log<level::ERR>("Uncaught DBus service lookup failure exception",
                        entry("PATH=%s", e.path.c_str()),
                        entry("INTERFACE=%s", e.interface.c_str()));
    }
    catch (const phosphor::fan::util::DBusMethodError& e)
    {
        log<level::ERR>("Uncaught DBus method failure exception",
                        entry("BUSNAME=%s", e.busName.c_str()),
                        entry("PATH=%s", e.path.c_str()),
                        entry("INTERFACE=%s", e.interface.c_str()),
                        entry("METHOD=%s", e.method.c_str()));
    }
    catch (const phosphor::fan::util::DBusPropertyError& e)
    {
        log<level::ERR>("Uncaught DBus property access failure exception",
                        entry("BUSNAME=%s", e.busName.c_str()),
                        entry("PATH=%s", e.path.c_str()),
                        entry("INTERFACE=%s", e.interface.c_str()),
                        entry("PROPERTY=%s", e.property.c_str()));
    }
    catch (std::exception& e)
    {
#ifdef CONTROL_USE_JSON
        phosphor::fan::control::json::FlightRecorder::instance().log(
            "main", "Unexpected exception exit");
        dumpFlightRecorder();
#endif
        throw;
    }

#ifdef CONTROL_USE_JSON
    phosphor::fan::control::json::FlightRecorder::instance().log(
        "main", "Abnormal exit");
    dumpFlightRecorder();
#endif

    return 1;
}
