// Copyright (c) 2021 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 "cpuinfo_utils.hpp"

// Include the server headers to get the enum<->string conversion functions
#include <boost/algorithm/string/predicate.hpp>
#include <sdbusplus/asio/property.hpp>
#include <xyz/openbmc_project/State/Host/server.hpp>
#include <xyz/openbmc_project/State/OperatingSystem/Status/server.hpp>

#include <iostream>
#include <type_traits>
#include <utility>
#include <variant>

namespace cpu_info
{

using namespace sdbusplus::server::xyz::openbmc_project;
using PowerState = state::Host::HostState;
using OsState = state::operating_system::Status::OSStatus;

HostState hostState = HostState::off;
static PowerState powerState = PowerState::Off;
static OsState osState = OsState::Inactive;
static bool biosDone = false;
static std::vector<HostStateHandler> hostStateCallbacks;

static std::shared_ptr<sdbusplus::asio::connection> dbusConn;

void addHostStateCallback(HostStateHandler cb)
{
    hostStateCallbacks.push_back(cb);
}

static void updateHostState()
{
    HostState prevState = hostState;
    if (powerState == PowerState::Off)
    {
        hostState = HostState::off;
        // Make sure that we don't inadvertently jump back to PostComplete if
        // the HW status happens to turn back on before the biosDone goes false,
        // since the two signals come from different services and there is no
        // tight guarantee about their relationship.
        biosDone = false;
        // Setting osState to inactive for the same reason as above.
        osState = OsState::Inactive;
    }
    // Both biosDone and OsState tell us about the POST done status. At least
    // one of them should indicate that the POST is done.
    // According to openbmc_project/State/OperatingSystem/Status.interface.yaml
    // Only "Inactive" indicates that the POST is not done. All the other
    // statuses (CBoot, PXEBoot, DiagBoot, CDROMBoot, ROMBoot, BootComplete,
    // Standby) indicate that the POST is done.
    else if ((!biosDone) && (osState == OsState::Inactive))
    {
        hostState = HostState::postInProgress;
    }
    else
    {
        hostState = HostState::postComplete;
    }
    DEBUG_PRINT << "new host state: " << static_cast<int>(hostState) << "\n";

    if (prevState != hostState)
    {
        for (const auto& cb : hostStateCallbacks)
        {
            cb(prevState, hostState);
        }
    }
}

void updatePowerState(const std::string& newState)
{
    powerState = state::Host::convertHostStateFromString(newState);
    updateHostState();
}

void updateBiosDone(bool newState)
{
    biosDone = newState;
    updateHostState();
}

void updateOsState(const std::string& newState)
{
    // newState might not contain the full path. It might just contain the enum
    // string (By the time I am writing this, its not returning the full path).
    // Full string:
    // "xyz.openbmc_project.State.OperatingSystem.Status.OSStatus.Standby". Just
    // the string for enum: "Standby". If the newState doesn't contain the full
    // string, convertOSStatusFromString will fail. Prepend the full path if
    // needed.
    std::string full_path = newState;
    if (newState.find("xyz.") == std::string::npos)
    {
        full_path =
            "xyz.openbmc_project.State.OperatingSystem.Status.OSStatus." +
            newState;
    }

    try
    {
        osState = state::operating_system::Status::convertOSStatusFromString(
            full_path);
    }
    catch (const sdbusplus::exception::InvalidEnumString& ex)
    {
        std::cerr << "Invalid OperatingSystem Status: " << full_path << "\n";
        osState = OsState::Inactive;
    }
    updateHostState();
}

/**
 * Register a handler to be called whenever the given property is changed. Also
 * call the handler once immediately (asynchronously) with the current property
 * value.
 *
 * Since this necessarily reads all properties in the given interface, type
 * information about the interface may need to be provided via
 * CustomVariantArgs.
 *
 * @tparam  CustomVariantTypes  Any property types contained in the interface
 *                              beyond the base data types (numeric and
 *                              string-like types) and Handler's param type.
 * @tparam  Handler     Automatically deduced. Must be a callable taking a
 *                      single parameter whose type matches the property.
 *
 * @param[in]   service     D-Bus service name.
 * @param[in]   object      D-Bus object name.
 * @param[in]   interface   D-Bus interface name.
 * @param[in]   propertyName    D-Bus property name.
 * @param[in]   handler     Callable to be called immediately and upon any
 *                          changes in the property value.
 * @param[out]  propertiesChangedMatch  Optional pointer to receive a D-Bus
 *                                      match object, if you need to manage its
 *                                      lifetime.
 * @param[out]  interfacesAddedMatch    Optional pointer to receive a D-Bus
 *                                      match object, if you need to manage its
 *                                      lifetime.
 */
template <typename... CustomVariantTypes, typename Handler>
static void subscribeToProperty(
    const char* service, const char* object, const char* interface,
    const char* propertyName, Handler&& handler,
    sdbusplus::bus::match_t** propertiesChangedMatch = nullptr,
    sdbusplus::bus::match_t** interfacesAddedMatch = nullptr)
{
    // Type of first parameter to Handler, with const/& removed
    using PropertyType = std::remove_const_t<std::remove_reference_t<
        std::tuple_element_t<0, boost::callable_traits::args_t<Handler>>>>;
    // Base data types which we can handle by default
    using InterfaceVariant = typename sdbusplus::utility::dedup_variant_t<
        PropertyType, CustomVariantTypes..., bool, uint8_t, uint16_t, int16_t,
        uint32_t, int32_t, uint64_t, int64_t, size_t, ssize_t, double,
        std::string, sdbusplus::message::object_path>;

    sdbusplus::asio::getProperty<PropertyType>(
        *dbusConn, service, object, interface, propertyName,
        [handler, propertyName = std::string(propertyName)](
            boost::system::error_code ec, const PropertyType& newValue) {
            if (ec)
            {
                std::cerr << "Failed to read property " << propertyName << ": "
                          << ec << "\n";
                return;
            }
            handler(newValue);
        });

    using ChangedPropertiesType =
        std::vector<std::pair<std::string, InterfaceVariant>>;

    // Define some logic which is common to the two match callbacks, since they
    // both have to loop through all the properties in the interface.
    auto commonPropHandler = [propertyName = std::string(propertyName),
                              handler = std::forward<Handler>(handler)](
                                 const ChangedPropertiesType& changedProps) {
        for (const auto& [changedProp, newValue] : changedProps)
        {
            if (changedProp == propertyName)
            {
                const auto* actualVal = std::get_if<PropertyType>(&newValue);
                if (actualVal != nullptr)
                {
                    DEBUG_PRINT << "New value for " << propertyName << ": "
                                << *actualVal << "\n";
                    handler(*actualVal);
                }
                else
                {
                    std::cerr << "Property " << propertyName
                              << " had unexpected type\n";
                }
                break;
            }
        }
    };

    // Set up a match for PropertiesChanged signal
    auto* propMatch = new sdbusplus::bus::match_t(
        *dbusConn,
        sdbusplus::bus::match::rules::sender(service) +
            sdbusplus::bus::match::rules::propertiesChanged(object, interface),
        [commonPropHandler](sdbusplus::message_t& reply) {
            ChangedPropertiesType changedProps;
            // ignore first param (interface name), it has to be correct
            reply.read(std::string(), changedProps);

            DEBUG_PRINT << "PropertiesChanged handled\n";
            commonPropHandler(changedProps);
        });

    // Set up a match for the InterfacesAdded signal from the service's
    // ObjectManager. This is useful in the case where the object is not added
    // yet, and when it's added they choose to not emit PropertiesChanged. So in
    // order to see the initial value when it comes, we need to watch this too.
    auto* intfMatch = new sdbusplus::bus::match_t(
        *dbusConn,
        sdbusplus::bus::match::rules::sender(service) +
            sdbusplus::bus::match::rules::interfacesAdded(),
        [object = std::string(object), interface = std::string(interface),
         commonPropHandler](sdbusplus::message_t& reply) {
            sdbusplus::message::object_path changedObject;
            reply.read(changedObject);
            if (changedObject != object)
            {
                return;
            }

            std::vector<std::pair<std::string, ChangedPropertiesType>>
                changedInterfaces;
            reply.read(changedInterfaces);

            for (const auto& [changedInterface, changedProps] :
                 changedInterfaces)
            {
                if (changedInterface != interface)
                {
                    continue;
                }

                DEBUG_PRINT << "InterfacesAdded handled\n";
                commonPropHandler(changedProps);
            }
        });

    if (propertiesChangedMatch != nullptr)
    {
        *propertiesChangedMatch = propMatch;
    }

    if (interfacesAddedMatch != nullptr)
    {
        *interfacesAddedMatch = intfMatch;
    }
}

void hostStateSetup(const std::shared_ptr<sdbusplus::asio::connection>& conn)
{
    static bool initialized = false;
    if (initialized)
    {
        return;
    }

    dbusConn = conn;

    // Leak the returned match objects. We want them to run forever.
    subscribeToProperty(
        "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
        state::Host::interface, "CurrentHostState", updatePowerState);
    subscribeToProperty("xyz.openbmc_project.Host.Misc.Manager",
                        "/xyz/openbmc_project/misc/platform_state",
                        "xyz.openbmc_project.State.Host.Misc", "CoreBiosDone",
                        updateBiosDone);
    // xyz.openbmc_project.Host.Misc.Manager has Intel specific dependencies.
    // If it is not available, then we can use the OperatingSystemState in
    // xyz.openbmc_project.State.OperatingSystem. According to x86-power-control
    // repo, OperatingSystemState should return "standby" once the POST is
    // asserted.
    subscribeToProperty("xyz.openbmc_project.State.OperatingSystem",
                        "/xyz/openbmc_project/state/os",
                        "xyz.openbmc_project.State.OperatingSystem.Status",
                        "OperatingSystemState", updateOsState);

    initialized = true;
}

namespace dbus
{
boost::asio::io_context& getIOContext()
{
    static boost::asio::io_context ioc;
    return ioc;
}
std::shared_ptr<sdbusplus::asio::connection> getConnection()
{
    static auto conn =
        std::make_shared<sdbusplus::asio::connection>(getIOContext());
    return conn;
}
} // namespace dbus
} // namespace cpu_info
