/*
// Copyright (c) 2019 Intel 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 "xyz/openbmc_project/Common/error.hpp"

#include <ipmid/api.hpp>
#include <ipmid/utils.hpp>
#include <nlohmann/json.hpp>
#include <phosphor-logging/elog-errors.hpp>
#include <phosphor-logging/log.hpp>
#include <sdbusplus/timer.hpp>
#include <xyz/openbmc_project/Control/Power/RestorePolicy/server.hpp>

#include <fstream>
#include <iostream>
#include <regex>
#include <stdexcept>
#include <string_view>

using namespace phosphor::logging;

namespace ipmi::chassis
{
static constexpr const char* buttonIntf = "xyz.openbmc_project.Chassis.Buttons";

const static constexpr char* idButtonPath =
    "/xyz/openbmc_project/chassis/buttons/id";
static constexpr const char* powerButtonPath =
    "/xyz/openbmc_project/chassis/buttons/power";
static constexpr const char* resetButtonPath =
    "/xyz/openbmc_project/chassis/buttons/reset";
static constexpr const char* interruptButtonPath =
    "/xyz/openbmc_project/chassis/buttons/nmi";

const static constexpr char* idButtonProp = "ButtonPressed";

const static constexpr char* ledService =
    "xyz.openbmc_project.LED.GroupManager";
const static constexpr char* ledIDOnObj =
    "/xyz/openbmc_project/led/groups/enclosure_identify";
const static constexpr char* ledIDBlinkObj =
    "/xyz/openbmc_project/led/groups/enclosure_identify_blink";
const static constexpr char* ledInterface = "xyz.openbmc_project.Led.Group";
const static constexpr char* ledProp = "Asserted";
enum class ChassisIDState
{
    off = 0,
    temporary = 1,
    indefinite = 2,
};
static ChassisIDState chassisIDState = ChassisIDState::off;

constexpr size_t defaultIdentifyTimeOut = 15;

std::unique_ptr<phosphor::Timer> identifyTimer
    __attribute__((init_priority(101)));
std::unique_ptr<sdbusplus::bus::match_t> matchPtr
    __attribute__((init_priority(101)));

static void registerChassisFunctions() __attribute__((constructor));

static ipmi::ServiceCache LEDService(ledInterface, ledIDBlinkObj);

void enclosureIdentifyLed(const char* objName, bool isIdLedOn)
{
    auto bus = getSdBus();

    try
    {
        std::string service = LEDService.getService(*bus);
        setDbusProperty(*bus, service, objName, ledInterface, ledProp,
                        isIdLedOn);
    }
    catch (const std::exception& e)
    {
        log<level::ERR>("enclosureIdentifyLed: can't set property",
                        entry("ERR=%s", e.what()));
    }
}

bool getIDState(const char* objName, bool& state)
{
    auto bus = getSdBus();

    try
    {
        std::string service = LEDService.getService(*bus);
        ipmi::Value enabled = getDbusProperty(*bus, service, objName,
                                              ledInterface, ledProp);
        state = std::get<bool>(enabled);
    }
    catch (const sdbusplus::exception_t& e)
    {
        log<level::ERR>("Fail to get property", entry("PATH=%s", objName),
                        entry("ERROR=%s", e.what()));
        return false;
    }
    return true;
}

void enclosureIdentifyLedBlinkOff()
{
    chassisIDState = ChassisIDState::off;
    enclosureIdentifyLed(ledIDBlinkObj, false);
}

void idButtonPropChanged(sdbusplus::message_t& msg)
{
    bool asserted = false;
    bool buttonPressed = false;

    std::map<std::string, ipmi::Value> props;
    std::vector<std::string> inval;
    std::string iface;
    msg.read(iface, props, inval);

    for (const auto& t : props)
    {
        auto key = t.first;
        auto value = t.second;

        if (key == idButtonProp)
        {
            buttonPressed = std::get<bool>(value);
        }
        break;
    }

    if (buttonPressed)
    {
        if (identifyTimer->isRunning())
        {
            log<level::INFO>("ID timer is running");
        }

        // make sure timer is stopped
        identifyTimer->stop();

        if (!getIDState(ledIDBlinkObj, asserted))
        {
            return;
        }

        if (asserted)
        {
            // LED is blinking, turn off the LED
            chassisIDState = ChassisIDState::off;
            enclosureIdentifyLed(ledIDBlinkObj, false);
            enclosureIdentifyLed(ledIDOnObj, false);
        }
        else
        {
            // toggle the IED on/off
            if (!getIDState(ledIDOnObj, asserted))
            {
                return;
            }
            enclosureIdentifyLed(ledIDOnObj, !asserted);
        }
    }
}

void createIdentifyTimer()
{
    if (!identifyTimer)
    {
        identifyTimer =
            std::make_unique<phosphor::Timer>(enclosureIdentifyLedBlinkOff);
    }
}

ipmi::RspType<> ipmiChassisIdentify(std::optional<uint8_t> interval,
                                    std::optional<uint8_t> force)
{
    uint8_t identifyInterval = interval.value_or(defaultIdentifyTimeOut);
    bool forceIdentify = force.value_or(0) & 0x01;

    enclosureIdentifyLed(ledIDOnObj, false);
    identifyTimer->stop();

    if (identifyInterval || forceIdentify)
    {
        enclosureIdentifyLed(ledIDBlinkObj, true);
        if (forceIdentify)
        {
            chassisIDState = ChassisIDState::indefinite;
            return ipmi::responseSuccess();
        }
        chassisIDState = ChassisIDState::temporary;
        // start the timer
        auto time = std::chrono::duration_cast<std::chrono::microseconds>(
            std::chrono::seconds(identifyInterval));
        identifyTimer->start(time);
    }
    else
    {
        chassisIDState = ChassisIDState::off;
        enclosureIdentifyLed(ledIDBlinkObj, false);
    }
    return ipmi::responseSuccess();
}

namespace power_policy
{
/* helper function for Get Chassis Status Command
 */
std::optional<uint2_t> getPowerRestorePolicy()
{
    constexpr const char* powerRestorePath =
        "/xyz/openbmc_project/control/host0/power_restore_policy";
    constexpr const char* powerRestoreIntf =
        "xyz.openbmc_project.Control.Power.RestorePolicy";
    uint2_t restorePolicy = 0;
    std::shared_ptr<sdbusplus::asio::connection> busp = getSdBus();

    try
    {
        auto service = ipmi::getService(*busp, powerRestoreIntf,
                                        powerRestorePath);

        ipmi::Value result =
            ipmi::getDbusProperty(*busp, service, powerRestorePath,
                                  powerRestoreIntf, "PowerRestorePolicy");
        auto powerRestore = sdbusplus::xyz::openbmc_project::Control::Power::
            server::RestorePolicy::convertPolicyFromString(
                std::get<std::string>(result));

        using namespace sdbusplus::xyz::openbmc_project::Control::Power::server;
        switch (powerRestore)
        {
            case RestorePolicy::Policy::AlwaysOff:
                restorePolicy = 0x00;
                break;
            case RestorePolicy::Policy::Restore:
                restorePolicy = 0x01;
                break;
            case RestorePolicy::Policy::AlwaysOn:
                restorePolicy = 0x02;
                break;
            default:
                break;
        }
    }
    catch (const std::exception& e)
    {
        log<level::ERR>("Failed to fetch PowerRestorePolicy property",
                        entry("ERROR=%s", e.what()),
                        entry("PATH=%s", powerRestorePath),
                        entry("INTERFACE=%s", powerRestoreIntf));
        return std::nullopt;
    }
    return std::make_optional(restorePolicy);
}

/*
 * getPowerStatus
 * helper function for Get Chassis Status Command
 * return - optional value for pgood (no value on error)
 */
std::optional<bool> getPowerStatus()
{
    bool powerGood = false;
    std::shared_ptr<sdbusplus::asio::connection> busp = getSdBus();
    try
    {
        constexpr const char* chassisStatePath =
            "/xyz/openbmc_project/state/chassis0";
        constexpr const char* chassisStateIntf =
            "xyz.openbmc_project.State.Chassis";
        auto service = ipmi::getService(*busp, chassisStateIntf,
                                        chassisStatePath);

        ipmi::Value variant =
            ipmi::getDbusProperty(*busp, service, chassisStatePath,
                                  chassisStateIntf, "CurrentPowerState");
        std::string powerState = std::get<std::string>(variant);
        if (powerState == "xyz.openbmc_project.State.Chassis.PowerState.On")
        {
            powerGood = true;
        }
    }
    catch (const std::exception& e)
    {
        log<level::ERR>("Failed to fetch power state property",
                        entry("ERROR=%s", e.what()));
        return std::nullopt;
    }
    return std::make_optional(powerGood);
}

/*
 * getACFailStatus
 * helper function for Get Chassis Status Command
 * return - bool value for ACFail (false on error)
 */
bool getACFailStatus()
{
    constexpr const char* acBootObj =
        "/xyz/openbmc_project/control/host0/ac_boot";
    constexpr const char* acBootIntf = "xyz.openbmc_project.Common.ACBoot";
    std::string acFail;
    std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
    try
    {
        auto service = ipmi::getService(*bus, acBootIntf, acBootObj);

        ipmi::Value variant = ipmi::getDbusProperty(*bus, service, acBootObj,
                                                    acBootIntf, "ACBoot");
        acFail = std::get<std::string>(variant);
    }
    catch (const std::exception& e)
    {
        log<level::ERR>(
            "Failed to fetch ACBoot property", entry("ERROR=%s", e.what()),
            entry("PATH=%s", acBootObj), entry("INTERFACE=%s", acBootIntf));
    }
    return acFail == "True";
}
} // namespace power_policy

static std::optional<bool> getButtonEnabled(const std::string& buttonPath)
{
    bool buttonDisabled = false;
    std::shared_ptr<sdbusplus::asio::connection> busp = getSdBus();
    try
    {
        auto service = ipmi::getService(*getSdBus(), buttonIntf, buttonPath);
        ipmi::Value disabled = ipmi::getDbusProperty(
            *busp, service, buttonPath, buttonIntf, "ButtonMasked");
        buttonDisabled = std::get<bool>(disabled);
    }
    catch (const sdbusplus::exception_t& e)
    {
        log<level::ERR>("Fail to get button disabled property",
                        entry("PATH=%s", buttonPath.c_str()),
                        entry("ERROR=%s", e.what()));
        return std::nullopt;
    }
    return std::make_optional(buttonDisabled);
}

static bool setButtonEnabled(const std::string& buttonPath, const bool disabled)
{
    try
    {
        auto service = ipmi::getService(*getSdBus(), buttonIntf, buttonPath);
        ipmi::setDbusProperty(*getSdBus(), service, buttonPath, buttonIntf,
                              "ButtonMasked", disabled);
    }
    catch (const std::exception& e)
    {
        log<level::ERR>("Failed to set button disabled",
                        entry("EXCEPTION=%s, REQUEST=%x", e.what(), disabled));
        return -1;
    }

    return 0;
}

static bool getRestartCause(ipmi::Context::ptr& ctx, std::string& restartCause)
{
    constexpr const char* restartCausePath =
        "/xyz/openbmc_project/control/host0/restart_cause";
    constexpr const char* restartCauseIntf =
        "xyz.openbmc_project.Control.Host.RestartCause";

    std::string service;
    boost::system::error_code ec = ipmi::getService(ctx, restartCauseIntf,
                                                    restartCausePath, service);

    if (!ec)
    {
        ec = ipmi::getDbusProperty(ctx, service, restartCausePath,
                                   restartCauseIntf, "RestartCause",
                                   restartCause);
    }
    if (ec)
    {
        log<level::ERR>("Failed to fetch RestartCause property",
                        entry("ERROR=%s", ec.message().c_str()),
                        entry("PATH=%s", restartCausePath),
                        entry("INTERFACE=%s", restartCauseIntf));
        return false;
    }
    return true;
}

static bool checkIPMIRestartCause(ipmi::Context::ptr& ctx,
                                  bool& ipmiRestartCause)
{
    std::string restartCause;
    if (!getRestartCause(ctx, restartCause))
    {
        return false;
    }
    ipmiRestartCause =
        (restartCause ==
         "xyz.openbmc_project.State.Host.RestartCause.IpmiCommand");
    return true;
}

//----------------------------------------------------------------------
// Get Chassis Status commands
//----------------------------------------------------------------------
ipmi::RspType<bool,    // Power is on
              bool,    // Power overload
              bool,    // Interlock
              bool,    // power fault
              bool,    // power control fault
              uint2_t, // power restore policy
              bool,    // reserved

              bool,    // AC failed
              bool,    // last power down caused by a Power overload
              bool,    // last power down caused by a power interlock
              bool,    // last power down caused by power fault
              bool, // last ‘Power is on’ state was entered via IPMI command
              uint3_t, // reserved

              bool,    // Chassis intrusion active
              bool,    // Front Panel Lockout active
              bool,    // Drive Fault
              bool,    // Cooling/fan fault detected
              uint2_t, // Chassis Identify State
              bool,    // Chassis Identify command and state info supported
              bool,    // reserved

              bool,    // Power off button disabled
              bool,    // Reset button disabled
              bool,    // Diagnostic Interrupt button disabled
              bool,    // Standby (sleep) button disabled
              bool,    // Power off button disable allowed
              bool,    // Reset button disable allowed
              bool,    // Diagnostic Interrupt button disable allowed
              bool     // Standby (sleep) button disable allowed
              >
    ipmiGetChassisStatus(ipmi::Context::ptr ctx)
{
    std::optional<uint2_t> restorePolicy =
        power_policy::getPowerRestorePolicy();
    std::optional<bool> powerGood = power_policy::getPowerStatus();
    if (!restorePolicy || !powerGood)
    {
        return ipmi::responseUnspecifiedError();
    }

    //  Front Panel Button Capabilities and disable/enable status(Optional)
    std::optional<bool> powerButtonReading = getButtonEnabled(powerButtonPath);
    // allow disable if the interface is present
    bool powerButtonDisableAllow = static_cast<bool>(powerButtonReading);
    // default return the button is enabled (not disabled)
    bool powerButtonDisabled = false;
    if (powerButtonDisableAllow)
    {
        // return the real value of the button status, if present
        powerButtonDisabled = *powerButtonReading;
    }

    std::optional<bool> resetButtonReading = getButtonEnabled(resetButtonPath);
    // allow disable if the interface is present
    bool resetButtonDisableAllow = static_cast<bool>(resetButtonReading);
    // default return the button is enabled (not disabled)
    bool resetButtonDisabled = false;
    if (resetButtonDisableAllow)
    {
        // return the real value of the button status, if present
        resetButtonDisabled = *resetButtonReading;
    }

    std::optional<bool> interruptButtonReading =
        getButtonEnabled(interruptButtonPath);
    // allow disable if the interface is present
    bool interruptButtonDisableAllow =
        static_cast<bool>(interruptButtonReading);
    // default return the button is enabled (not disabled)
    bool interruptButtonDisabled = false;
    if (interruptButtonDisableAllow)
    {
        // return the real value of the button status, if present
        interruptButtonDisabled = *interruptButtonReading;
    }

    bool powerDownAcFailed = power_policy::getACFailStatus();

    bool powerStatusIPMI = false;
    if (!checkIPMIRestartCause(ctx, powerStatusIPMI))
    {
        return ipmi::responseUnspecifiedError();
    }

    bool chassisIntrusionActive = false;
    constexpr const char* chassisIntrusionObj =
        "/xyz/openbmc_project/Chassis/Intrusion";
    constexpr const char* chassisIntrusionInf =
        "xyz.openbmc_project.Chassis.Intrusion";

    std::string intrusionService;
    boost::system::error_code ec = ipmi::getService(
        ctx, chassisIntrusionInf, chassisIntrusionObj, intrusionService);
    if (ec)
    {
        log<level::ERR>("Failed to get Chassis Intrusion service",
                        entry("ERROR=%s", ec.message().c_str()));
    }

    chassisIntrusionActive = !intrusionService.empty();

    // This response has a lot of hard-coded, unsupported fields
    // They are set to false or 0
    constexpr bool powerOverload = false;
    constexpr bool chassisInterlock = false;
    constexpr bool powerFault = false;
    constexpr bool powerControlFault = false;
    constexpr bool powerDownOverload = false;
    constexpr bool powerDownInterlock = false;
    constexpr bool powerDownPowerFault = false;
    constexpr bool frontPanelLockoutActive = false;
    constexpr bool driveFault = false;
    constexpr bool coolingFanFault = false;
    // chassisIdentifySupport set because this command is implemented
    constexpr bool chassisIdentifySupport = true;
    uint2_t chassisIdentifyState = types::enum_cast<uint2_t>(chassisIDState);
    constexpr bool sleepButtonDisabled = false;
    constexpr bool sleepButtonDisableAllow = false;

    return ipmi::responseSuccess(
        *powerGood, powerOverload, chassisInterlock, powerFault,
        powerControlFault, *restorePolicy,
        false, // reserved

        powerDownAcFailed, powerDownOverload, powerDownInterlock,
        powerDownPowerFault, powerStatusIPMI,
        uint3_t(0), // reserved

        chassisIntrusionActive, frontPanelLockoutActive, driveFault,
        coolingFanFault, chassisIdentifyState, chassisIdentifySupport,
        false, // reserved

        powerButtonDisabled, resetButtonDisabled, interruptButtonDisabled,
        sleepButtonDisabled, powerButtonDisableAllow, resetButtonDisableAllow,
        interruptButtonDisableAllow, sleepButtonDisableAllow);
}

static uint4_t getRestartCauseValue(const std::string& cause)
{
    uint4_t restartCauseValue = 0;
    if (cause == "xyz.openbmc_project.State.Host.RestartCause.Unknown")
    {
        restartCauseValue = 0x0;
    }
    else if (cause == "xyz.openbmc_project.State.Host.RestartCause.IpmiCommand")
    {
        restartCauseValue = 0x1;
    }
    else if (cause == "xyz.openbmc_project.State.Host.RestartCause.ResetButton")
    {
        restartCauseValue = 0x2;
    }
    else if (cause == "xyz.openbmc_project.State.Host.RestartCause.PowerButton")
    {
        restartCauseValue = 0x3;
    }
    else if (cause ==
             "xyz.openbmc_project.State.Host.RestartCause.WatchdogTimer")
    {
        restartCauseValue = 0x4;
    }
    else if (cause == "xyz.openbmc_project.State.Host.RestartCause.OEM")
    {
        restartCauseValue = 0x5;
    }
    else if (cause ==
             "xyz.openbmc_project.State.Host.RestartCause.PowerPolicyAlwaysOn")
    {
        restartCauseValue = 0x6;
    }
    else if (cause == "xyz.openbmc_project.State.Host.RestartCause."
                      "PowerPolicyPreviousState")
    {
        restartCauseValue = 0x7;
    }
    else if (cause == "xyz.openbmc_project.State.Host.RestartCause.PEFReset")
    {
        restartCauseValue = 0x8;
    }
    else if (cause ==
             "xyz.openbmc_project.State.Host.RestartCause.PEFPowerCycle")
    {
        restartCauseValue = 0x9;
    }
    else if (cause == "xyz.openbmc_project.State.Host.RestartCause.SoftReset")
    {
        restartCauseValue = 0xa;
    }
    else if (cause == "xyz.openbmc_project.State.Host.RestartCause.RTCWakeup")
    {
        restartCauseValue = 0xb;
    }
    return restartCauseValue;
}

ipmi::RspType<uint4_t, // Restart Cause
              uint4_t, // reserved
              uint8_t  // channel number
              >
    ipmiGetSystemRestartCause(ipmi::Context::ptr ctx)
{
    std::string restartCauseStr;
    if (!getRestartCause(ctx, restartCauseStr))
    {
        return ipmi::responseUnspecifiedError();
    }
    constexpr uint4_t reserved = 0;
    auto channel = static_cast<uint8_t>(ctx->channel);
    return ipmi::responseSuccess(getRestartCauseValue(restartCauseStr),
                                 reserved, channel);
}

ipmi::RspType<> ipmiSetFrontPanelButtonEnables(
    bool disablePowerButton, bool disableResetButton,
    bool disableInterruptButton, [[maybe_unused]] bool disableSleepButton,
    uint4_t reserved)
{
    if (reserved)
    {
        return ipmi::responseInvalidFieldRequest();
    }
    bool error = false;

    error |= setButtonEnabled(powerButtonPath, disablePowerButton);
    error |= setButtonEnabled(resetButtonPath, disableResetButton);
    error |= setButtonEnabled(interruptButtonPath, disableInterruptButton);

    if (error)
    {
        return ipmi::responseUnspecifiedError();
    }

    return ipmi::responseSuccess();
}

static void registerChassisFunctions(void)
{
    log<level::INFO>("Registering Chassis commands");

    createIdentifyTimer();

    if (matchPtr == nullptr)
    {
        using namespace sdbusplus::bus::match::rules;
        auto bus = getSdBus();

        matchPtr = std::make_unique<sdbusplus::bus::match_t>(
            *bus,
            sdbusplus::bus::match::rules::propertiesChanged(idButtonPath,
                                                            buttonIntf),
            std::bind(idButtonPropChanged, std::placeholders::_1));
    }

    // <Chassis Identify>
    ipmi::registerHandler(ipmi::prioOemBase, ipmi::netFnChassis,
                          ipmi::chassis::cmdChassisIdentify,
                          ipmi::Privilege::Operator, ipmiChassisIdentify);
    // <Get Chassis Status>
    ipmi::registerHandler(ipmi::prioOemBase, ipmi::netFnChassis,
                          ipmi::chassis::cmdGetChassisStatus,
                          ipmi::Privilege::User, ipmiGetChassisStatus);
    // <Get System Restart Cause>
    ipmi::registerHandler(ipmi::prioOemBase, ipmi::netFnChassis,
                          ipmi::chassis::cmdGetSystemRestartCause,
                          ipmi::Privilege::User, ipmiGetSystemRestartCause);
    // <Set Front Panel Enables>
    ipmi::registerHandler(ipmi::prioOemBase, ipmi::netFnChassis,
                          ipmi::chassis::cmdSetFrontPanelButtonEnables,
                          ipmi::Privilege::Admin,
                          ipmiSetFrontPanelButtonEnables);
}

} // namespace ipmi::chassis
