/*
// Copyright (c) 2018 Intel Corporation
// Copyright (c) 2018 Ampere Computing LLC
/
// 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.
*/
#pragma once

#include "app.hpp"
#include "dbus_utility.hpp"
#include "query.hpp"
#include "registries/privilege_registry.hpp"
#include "sensors.hpp"
#include "utils/chassis_utils.hpp"

#include <sdbusplus/asio/property.hpp>

#include <array>
#include <string_view>

#include "managed_store.hpp"

#ifdef UNIT_TEST_BUILD
#include "test/g3/mock_managed_store.hpp" // NOLINT
#endif

namespace redfish
{

inline void afterGetPowerCapEnable(
    const std::shared_ptr<SensorsAsyncResp>& sensorsAsyncResp,
    uint32_t valueToSet, const std::string& powerCapService,
    const boost::system::error_code& ec, bool powerCapEnable)
{
    if (ec)
    {
        messages::internalError(sensorsAsyncResp->asyncResp->res);
        BMCWEB_LOG_ERROR << "powerCapEnable Get handler: Dbus error " << ec;
        return;
    }
    if (!powerCapEnable)
    {
        messages::actionNotSupported(
            sensorsAsyncResp->asyncResp->res,
            "Setting LimitInWatts when PowerLimit feature is disabled");
        BMCWEB_LOG_ERROR << "PowerLimit feature is disabled ";
        return;
    }

    managedStore::GetManagedObjectStore()->setProperty(
        powerCapService,
        "/xyz/openbmc_project/control/host0/power_cap",
        "xyz.openbmc_project.Control.Power.Cap", "PowerCap", valueToSet,
        [sensorsAsyncResp](const boost::system::error_code& ec2) {
        if (ec2)
        {
            BMCWEB_LOG_DEBUG << "Power Limit Set: Dbus error: " << ec2;
            messages::internalError(sensorsAsyncResp->asyncResp->res);
            return;
        }
        sensorsAsyncResp->asyncResp->res.result(
            boost::beast::http::status::no_content);
    });
}

inline void afterGetDbusObjectPatch(
    const std::shared_ptr<SensorsAsyncResp>& sensorsAsyncResp,
    uint32_t valueToSet, const boost::system::error_code& ec,
    const dbus::utility::MapperGetObject& objects)
{
    std::string powerCapService;
    if (ec)
    {
        BMCWEB_LOG_WARNING << "powerCapEnable Get handler: Dbus error " << ec;
        return;
    }

    if (objects.size() != 1)
    {
        BMCWEB_LOG_WARNING
            << "Unexpected number of Power cap services Expected: 1, found: "
            << objects.size();
        return;
    }
    powerCapService = objects[0].first;
    managedStore::ManagedObjectStoreContext context(sensorsAsyncResp->asyncResp);
    dbus_utils::getProperty<bool>(
        powerCapService,
        "/xyz/openbmc_project/control/host0/power_cap",
        "xyz.openbmc_project.Control.Power.Cap", "PowerCapEnable",
        context,
        std::bind_front(afterGetPowerCapEnable, sensorsAsyncResp, valueToSet,
                        powerCapService));
}

inline void afterGetChassisPath(
    const std::shared_ptr<SensorsAsyncResp>& sensorsAsyncResp,
    std::vector<nlohmann::json>& powerControlCollections,
    const std::optional<std::string>& chassisPath)
{
    if (!chassisPath)
    {
        BMCWEB_LOG_WARNING << "Don't find valid chassis path ";
        messages::resourceNotFound(sensorsAsyncResp->asyncResp->res, "Chassis",
                                   sensorsAsyncResp->chassisId);
        return;
    }

    if (powerControlCollections.size() != 1)
    {
        BMCWEB_LOG_WARNING << "Don't support multiple hosts at present ";
        messages::resourceNotFound(sensorsAsyncResp->asyncResp->res, "Power",
                                   "PowerControl");
        return;
    }

    auto& item = powerControlCollections[0];

    std::optional<nlohmann::json> powerLimit;
    if (!json_util::readJson(item, sensorsAsyncResp->asyncResp->res,
                             "PowerLimit", powerLimit))
    {
        return;
    }
    if (!powerLimit)
    {
        return;
    }
    std::optional<uint32_t> value;
    if (!json_util::readJson(*powerLimit, sensorsAsyncResp->asyncResp->res,
                             "LimitInWatts", value))
    {
        return;
    }
    if (!value)
    {
        return;
    }

    constexpr std::array<std::string_view, 1> interfaces = {
        "xyz.openbmc_project.Control.Power.Cap"};

    managedStore::ManagedObjectStoreContext context(sensorsAsyncResp->asyncResp);
    dbus_utils::getDbusObject(
        "/xyz/openbmc_project/control/host0/power_cap", interfaces, context,
        std::bind_front(afterGetDbusObjectPatch, sensorsAsyncResp, *value));
}

inline void afterPowerCapSettingGet(
    const std::shared_ptr<SensorsAsyncResp>& sensorAsyncResp,
    const boost::system::error_code& ec,
    const dbus::utility::DBusPropertiesMap& properties)
{
    if (ec)
    {
        messages::internalError(sensorAsyncResp->asyncResp->res);
        BMCWEB_LOG_ERROR << "Power Limit GetAll handler: Dbus error " << ec;
        return;
    }

    nlohmann::json& tempArray =
        sensorAsyncResp->asyncResp->res.jsonValue["PowerControl"];

    // Put multiple "sensors" into a single PowerControl, 0,
    // so only create the first one
    if (tempArray.empty())
    {
        // Mandatory properties odata.id and MemberId
        // A warning without a odata.type
        nlohmann::json::object_t powerControl;
        powerControl["@odata.type"] = "#Power.v1_0_0.PowerControl";
        powerControl["@odata.id"] = "/redfish/v1/Chassis/" +
                                    sensorAsyncResp->chassisId +
                                    "/Power#/PowerControl/0";
        powerControl["Name"] = "Chassis Power Control";
        powerControl["MemberId"] = "0";
        tempArray.emplace_back(std::move(powerControl));
    }

    nlohmann::json& sensorJson = tempArray.back();
    bool enabled = false;
    double powerCap = 0.0;
    int64_t scale = 0;
    uint32_t limitMin = 0;
    uint32_t limitMax = 0;

    for (const std::pair<std::string, dbus::utility::DbusVariantType>&
             property : properties)
    {
        if (property.first == "Scale")
        {
            const int64_t* i = std::get_if<int64_t>(&property.second);

            if (i != nullptr)
            {
                scale = *i;
            }
        }
        else if (property.first == "PowerCap")
        {
            const double* d = std::get_if<double>(&property.second);
            const int64_t* i = std::get_if<int64_t>(&property.second);
            const uint32_t* u = std::get_if<uint32_t>(&property.second);

            if (d != nullptr)
            {
                powerCap = *d;
            }
            else if (i != nullptr)
            {
                powerCap = static_cast<double>(*i);
            }
            else if (u != nullptr)
            {
                powerCap = *u;
            }
        }
        else if (property.first == "PowerCapEnable")
        {
            const bool* b = std::get_if<bool>(&property.second);

            if (b != nullptr)
            {
                enabled = *b;
            }
        }
        else if (property.first == "MinPowerCapValue")
        {
            const uint32_t* u = std::get_if<uint32_t>(&property.second);
            if (u != nullptr)
            {
                limitMin = *u;
            }
        }
        else if (property.first == "MaxPowerCapValue")
        {
            const uint32_t* u = std::get_if<uint32_t>(&property.second);
            if (u != nullptr)
            {
                limitMax = *u;
            }
        }
    }

    // LimitException is Mandatory attribute as per OCP
    // Baseline Profile – v1.0.0, so currently making it
    // "NoAction" as default value to make it OCP Compliant.
    sensorJson["PowerLimit"]["LimitException"] = "NoAction";

    if (enabled)
    {
        // Redfish specification indicates PowerLimit should
        // be null if the limit is not enabled.
        sensorJson["PowerLimit"]["LimitInWatts"] =
            powerCap * std::pow(10, scale);
        sensorJson["PowerLimit"]["LimitMin"] = limitMin;
        sensorJson["PowerLimit"]["LimitMax"] = limitMax;
    }
}

inline void afterGetDbusObjectGetSettings(
    const std::shared_ptr<SensorsAsyncResp>& sensorsAsyncResp,
    const boost::system::error_code& ec,
    const dbus::utility::MapperGetObject& objects)
{
    std::string powerCapService;
    if (ec)
    {
        BMCWEB_LOG_WARNING << "powerCapEnable Get handler: Dbus error " << ec;
        return;
    }

    if (objects.size() != 1)
    {
        BMCWEB_LOG_WARNING
            << "Unexpected number of Power cap services Expected: 1, found: "
            << objects.size();
        return;
    }
    powerCapService = objects[0].first;
    managedStore::ManagedObjectStoreContext context(sensorsAsyncResp->asyncResp);
    managedStore::GetManagedObjectStore()->getAllProperties(
        powerCapService,
        "/xyz/openbmc_project/control/host0/power_cap",
        "xyz.openbmc_project.Control.Power.Cap",
        context,
        [sensorsAsyncResp](const boost::system::error_code& ec2,
                           const dbus::utility::DBusPropertiesMap& properties

        ) { afterPowerCapSettingGet(sensorsAsyncResp, ec2, properties); });
}

inline void getPowerState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                          const nlohmann::json::json_pointer& jsonPtr,
                          const std::string& service,
                          const std::string& objPath)
{
    managedStore::ManagedObjectStoreContext requestContext(asyncResp);
    dbus_utils::getProperty<bool>(
        service, objPath, "xyz.openbmc_project.Inventory.Item", "Present",
        requestContext,
        [asyncResp, jsonPtr, objPath](const boost::system::error_code& ec,
                                      bool present) {
        if (ec)
        {
            BMCWEB_LOG_DEBUG << "get presence failed for PowerState " << objPath
                             << " with error " << ec;

            if (ec.value() != EBADR)
            {
                messages::internalError(asyncResp->res);
            }
            return;
        }
        asyncResp->res.jsonValue[jsonPtr]["Status"]["State"] =
            present ? "Enabled" : "Absent";
        });
}

using Mapper = dbus::utility::MapperGetSubTreePathsResponse;
inline void
    afterGetChassis(const std::shared_ptr<SensorsAsyncResp>& sensorAsyncResp,
                    const boost::system::error_code& ec2,
                    const Mapper& chassisPaths)
{
    if (ec2)
    {
        BMCWEB_LOG_ERROR << "Power Limit GetSubTreePaths handler Dbus error "
                         << ec2;
        return;
    }

    bool found = false;
    for (const std::string& chassis : chassisPaths)
    {
        size_t len = std::string::npos;
        size_t lastPos = chassis.rfind('/');
        if (lastPos == std::string::npos)
        {
            continue;
        }

        if (lastPos == chassis.size() - 1)
        {
            size_t end = lastPos;
            lastPos = chassis.rfind('/', lastPos - 1);
            if (lastPos == std::string::npos)
            {
                continue;
            }

            len = end - (lastPos + 1);
        }

        std::string interfaceChassisName = chassis.substr(lastPos + 1, len);
        if (interfaceChassisName == sensorAsyncResp->chassisId)
        {
            found = true;
            break;
        }
    }

    if (!found)
    {
        BMCWEB_LOG_DEBUG << "Power Limit not present for "
                         << sensorAsyncResp->chassisId;
        return;
    }

    constexpr std::array<std::string_view, 1> interfaces = {
        "xyz.openbmc_project.Control.Power.Cap"};

    managedStore::ManagedObjectStoreContext context(sensorAsyncResp->asyncResp);
    dbus_utils::getDbusObject(
        "/xyz/openbmc_project/control/host0/power_cap", interfaces, context,
        std::bind_front(afterGetDbusObjectGetSettings, sensorAsyncResp));
}

inline void getPowerStateWithExpand(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const nlohmann::json::json_pointer& jsonPtr, const std::string& chassisName,
    const boost::system::error_code& ec, const Mapper& powerStatePaths)
{
    if (ec)
    {
        BMCWEB_LOG_ERROR
            << "PowerState Collection GetSubTreePaths handler Dbus error "
            << ec;
        return;
    }

    asyncResp->res.jsonValue[jsonPtr]["Oem"]["Google"]["@odata.type"] =
        "#GooglePower.v1_0_0.GooglePower";
    nlohmann::json& tempArray =
        asyncResp->res.jsonValue[jsonPtr]["Oem"]["Google"]["GooglePowerStates"];

    size_t powerStateMemberCount = 0;
    for (const std::string& powerState : powerStatePaths)
    {
        nlohmann::json::object_t powerStateObj;
        std::string powerStateId =
            sdbusplus::message::object_path(powerState).filename();
        BMCWEB_LOG_DEBUG << "Power State Id: " << powerStateId;
        powerStateObj["@odata.id"] = crow::utility::urlFromPieces(
            "redfish", "v1", "Chassis", chassisName, "Power", "Oem", "Google",
            "PowerStates", powerStateId);
        powerStateObj["@odata.type"] = "#GooglePowerState.GooglePowerState";
        powerStateObj["Id"] = powerStateId;
        powerStateObj["Name"] = "Power";
        nlohmann::json::json_pointer powerStateMemberPtr =
            jsonPtr / "Oem" / "Google" / "GooglePowerStates" /
            powerStateMemberCount;

        tempArray.emplace_back(std::move(powerStateObj));

        getPowerState(
            asyncResp, powerStateMemberPtr, "xyz.openbmc_project.EntityManager",
            "/xyz/openbmc_project/inventory/system/powerstate/" + powerStateId);

        powerStateMemberCount++;
    }
}

inline void
    handleChassisPowerGet(App& app, const crow::Request& req,
                          const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                          const std::string& chassisName)
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }
    asyncResp->res.jsonValue["PowerControl"] = nlohmann::json::array();

    auto sensorAsyncResp = std::make_shared<SensorsAsyncResp>(
        asyncResp, chassisName, sensors::dbus::powerPaths,
        sensors::node::power);

    getChassisData(sensorAsyncResp);

    // This callback verifies that the power limit is only provided
    // for the chassis that implements the Chassis inventory item.
    // This prevents things like power supplies providing the
    // chassis power limit

    constexpr std::array<std::string_view, 2> interfaces = {
        "xyz.openbmc_project.Inventory.Item.Board",
        "xyz.openbmc_project.Inventory.Item.Chassis"};

    managedStore::ManagedObjectStoreContext context(sensorAsyncResp->asyncResp);
    dbus_utils::getSubTreePaths(
        "/xyz/openbmc_project/inventory", 0, interfaces, context,
        std::bind_front(afterGetChassis, sensorAsyncResp));

    constexpr std::array<std::string_view, 1> powerStateIntf = {
        "xyz.openbmc_project.Inventory.Item.PowerState"};

    dbus_utils::getSubTreePaths(
        "/xyz/openbmc_project/inventory", 0, powerStateIntf, context,
        std::bind_front(getPowerStateWithExpand, asyncResp, ""_json_pointer,
                        chassisName));
}

inline void
    handleChassisPowerPatch(App& app, const crow::Request& req,
                            const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                            const std::string& chassisName)
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }
    auto sensorAsyncResp = std::make_shared<SensorsAsyncResp>(
        asyncResp, chassisName, sensors::dbus::powerPaths,
        sensors::node::power);

    std::optional<std::vector<nlohmann::json>> voltageCollections;
    std::optional<std::vector<nlohmann::json>> powerCtlCollections;

    if (!json_util::readJsonPatch(req, sensorAsyncResp->asyncResp->res,
                                  "PowerControl", powerCtlCollections,
                                  "Voltages", voltageCollections))
    {
        return;
    }

    if (powerCtlCollections)
    {
        redfish::chassis_utils::getValidChassisPath(
            sensorAsyncResp->asyncResp, sensorAsyncResp->chassisId,
            std::bind_front(afterGetChassisPath, sensorAsyncResp,
                            *powerCtlCollections));
    }
    if (voltageCollections)
    {
        std::unordered_map<std::string, std::vector<nlohmann::json>>
            allCollections;
        allCollections.emplace("Voltages", *std::move(voltageCollections));
        setSensorsOverride(sensorAsyncResp, allCollections);
    }
}

inline void handleChassisPowerStateGet(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& chassisName, const std::string& powerStateId)
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }
    BMCWEB_LOG_DEBUG << "Power State Id: " << powerStateId;
    asyncResp->res.jsonValue["@odata.id"] = crow::utility::urlFromPieces(
        "redfish", "v1", "Chassis", chassisName, "Power", "Oem", "Google",
        "PowerStates", powerStateId);
    asyncResp->res.jsonValue["@odata.type"] =
        "#GooglePowerState.GooglePowerState";
    asyncResp->res.jsonValue["Id"] = powerStateId;
    asyncResp->res.jsonValue["Name"] = "Power";
    getPowerState(
        asyncResp, ""_json_pointer, "xyz.openbmc_project.EntityManager",
        "/xyz/openbmc_project/inventory/system/powerstate/" + powerStateId);
}

inline void requestRoutesPower(App& app)
{
    BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/Power/")
        .privileges(redfish::privileges::getPower)
        .methods(boost::beast::http::verb::get)(
            std::bind_front(handleChassisPowerGet, std::ref(app)));

    BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/Power/")
        .privileges(redfish::privileges::patchPower)
        .methods(boost::beast::http::verb::patch)(
            std::bind_front(handleChassisPowerPatch, std::ref(app)));

    BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/Power/Oem/Google/PowerStates/")
        .privileges(redfish::privileges::getPower)
        .methods(boost::beast::http::verb::get)(
            std::bind_front(handleChassisPowerGet, std::ref(app)));

    BMCWEB_ROUTE(
        app, "/redfish/v1/Chassis/<str>/Power/Oem/Google/PowerStates/<str>/")
        .privileges(redfish::privileges::getPower)
        .methods(boost::beast::http::verb::get)(
            std::bind_front(handleChassisPowerStateGet, std::ref(app)));
}

} // namespace redfish
