/*
// 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 "pfr_mgr.hpp"

#include "file.hpp"

namespace pfr
{

inline void printVersion(const std::string& path, const std::string& version)
{
    lg2::info("VERSION INFO - {TYPE} - {VER}", "TYPE", path, "VER", version);
}
static constexpr uint8_t activeImage = 0;
static constexpr uint8_t recoveryImage = 1;

std::shared_ptr<sdbusplus::asio::dbus_interface> associationIface;
std::set<std::tuple<std::string, std::string, std::string>> associations;

using GetSubTreeType = std::vector<
    std::pair<std::string,
              std::vector<std::pair<std::string, std::vector<std::string>>>>>;

PfrVersion::PfrVersion(sdbusplus::asio::object_server& srv_,
                       std::shared_ptr<sdbusplus::asio::connection>& conn_,
                       const std::string& path_, const ImageType& imgType_,
                       const std::string& purpose_) :
    server(srv_), conn(conn_), path(path_), imgType(imgType_), purpose(purpose_)
{
    version = getFirmwareVersion(imgType);

    if (!(version == "0.0" || version.empty()))
    {
        printVersion(path, version);
    }

    std::string objPath = "/xyz/openbmc_project/software/" + path;
    versionIface =
        server.add_interface(objPath, "xyz.openbmc_project.Software.Version");

    if (versionIface != nullptr)
    {
        versionIface->register_property("Purpose", purpose);
        versionIface->register_property(
            versionStr, version,
            // Override set
            [this](const std::string& req, std::string& propertyValue) {
                if (internalSet)
                {
                    if (req != propertyValue)
                    {
                        version = req;
                        propertyValue = req;
                        return 1;
                    }
                }
                return 0;
            });

        versionIface->initialize();
    }

    std::string activation =
        "xyz.openbmc_project.Software.Activation.Activations.StandbySpare";

    if ((imgType == ImageType::bmcActive) ||
        (imgType == ImageType::biosActive) ||
        (imgType == ImageType::cpldActive) || (imgType == ImageType::afmActive))
    {
        // Running images so set Activations to "Active"
        activation =
            "xyz.openbmc_project.Software.Activation.Activations.Active";

        // For all Active images, functional endpoints must be added. This is
        // used in bmcweb & ipmi for fetching active component versions.

        // TODO: We have redundant active firmware version objects for BMC
        // and BIOS active images. BMC version is read from /etc/os-release
        // BIOS version is read from SMBIOS. Since it provides more
        // version information, Lets expose those as functional.
        // Down the line, Redundant inventory objects need to be addressed.
        if ((imgType == ImageType::cpldActive) ||
            (imgType == ImageType::afmActive))
        {
            associations.emplace("functional", "software_version", objPath);
        }
    }

    std::string reqActNone =
        "xyz.openbmc_project.Software.Activation.RequestedActivations.None";
    auto activationIface = server.add_interface(
        objPath, "xyz.openbmc_project.Software.Activation");

    if (activationIface != nullptr)
    {
        activationIface->register_property("Activation", activation);
        activationIface->register_property("RequestedActivation", reqActNone);

        activationIface->initialize();
    }

    // All the components exposed under PFR.Manager are updateable.
    // Lets add objPath endpoints to 'updatable' association
    associations.emplace("updateable", "software_version", objPath);
    associationIface->set_property("Associations", associations);
}

void PfrVersion::updateVersion()
{
    if (versionIface && versionIface->is_initialized())
    {
        std::string ver = getFirmwareVersion(imgType);
        printVersion(path, ver);
        internalSet = true;
        versionIface->set_property(versionStr, ver);
        internalSet = false;
    }
    return;
}

PfrConfig::PfrConfig(sdbusplus::asio::object_server& srv_,
                     std::shared_ptr<sdbusplus::asio::connection>& conn_) :
    server(srv_), conn(conn_)
{
    pfrCfgIface = server.add_interface("/xyz/openbmc_project/pfr",
                                       "xyz.openbmc_project.PFR.Attributes");

    ufmLocked = false;
    ufmProvisioned = false;
    ufmSupport = false;
    getProvisioningStatus(ufmLocked, ufmProvisioned, ufmSupport);

    pfrCfgIface->register_property(ufmProvisionedStr, ufmProvisioned,
                                   // Override set
                                   [this](const bool req, bool propertyValue) {
                                       if (internalSet)
                                       {
                                           if (req != propertyValue)
                                           {
                                               ufmProvisioned = req;
                                               propertyValue = req;
                                               return 1;
                                           }
                                       }
                                       return 0;
                                   });

    pfrCfgIface->register_property(ufmLockedStr, ufmLocked,
                                   // Override set
                                   [this](const bool req, bool propertyValue) {
                                       if (internalSet)
                                       {
                                           if (req != propertyValue)
                                           {
                                               ufmLocked = req;
                                               propertyValue = req;
                                               return 1;
                                           }
                                       }
                                       return 0;
                                   });

    pfrCfgIface->register_property(ufmSupportStr, ufmSupport,
                                   // Override set
                                   [this](const bool req, bool propertyValue) {
                                       if (internalSet)
                                       {
                                           if (req != propertyValue)
                                           {
                                               ufmSupport = req;
                                               propertyValue = req;
                                               return 1;
                                           }
                                       }
                                       return 0;
                                   });

    pfrCfgIface->initialize();

    /*BMCBusy period MailBox handling */
    pfrMBIface = server.add_interface("/xyz/openbmc_project/pfr",
                                      "xyz.openbmc_project.PFR.Mailbox");

    pfrMBIface->register_method("InitiateBMCBusyPeriod", [](bool setReset) {
        if (setBMCBusy(setReset) < 0)
        {
            return false;
        }
        return true;
    });

    pfrMBIface->register_method("ReadMBRegister", [](uint32_t regAddr) {
        uint8_t mailBoxReply = 0;
        try
        {
            getMBRegister(regAddr, mailBoxReply);
        }
        catch (const std::exception& e)
        {
            throw;
        }
        return mailBoxReply;
    });
    pfrMBIface->initialize();

    associationIface =
        server.add_interface("/xyz/openbmc_project/software",
                             "xyz.openbmc_project.Association.Definitions");
    associationIface->register_property("Associations", associations);
    associationIface->initialize();
}

void PfrConfig::updateProvisioningStatus()
{
    if (pfrCfgIface && pfrCfgIface->is_initialized())
    {
        bool lockVal = false;
        bool provVal = false;
        bool supportVal = false;
        getProvisioningStatus(lockVal, provVal, supportVal);
        internalSet = true;
        pfrCfgIface->set_property(ufmProvisionedStr, provVal);
        pfrCfgIface->set_property(ufmLockedStr, lockVal);
        pfrCfgIface->set_property(ufmSupportStr, supportVal);
        internalSet = false;
    }
    return;
}

static constexpr const char* postcodeStrProp = "PlatformState";
static constexpr const char* postcodeStrDefault = "Unknown";
static constexpr const char* postcodeDataProp = "Data";
static constexpr const char* postcodeIface =
    "xyz.openbmc_project.State.Boot.Platform";

PfrPostcode::PfrPostcode(sdbusplus::asio::object_server& srv_,
                         std::shared_ptr<sdbusplus::asio::connection>& conn_) :
    server(srv_), conn(conn_)
{
    if (getPlatformState(postcode) < 0)
    {
        postcode = 0;
    }

    pfrPostcodeIface =
        server.add_interface("/xyz/openbmc_project/pfr", postcodeIface);

    if (pfrPostcodeIface != nullptr)
    {
        pfrPostcodeIface->register_property(
            postcodeDataProp, postcode,
            // Override set
            [this](const uint8_t req, uint8_t& propertyValue) {
                if (internalSet)
                {
                    if (req != propertyValue)
                    {
                        postcode = req;
                        propertyValue = req;
                        return 1;
                    }
                }
                return 0;
            },
            [this](uint8_t& propertyValue) {
                updatePostcode();
                propertyValue = postcode;
                return propertyValue;
            });

        pfrPostcodeIface->register_property(postcodeStrProp,
                                            std::string(postcodeStrDefault));

        pfrPostcodeIface->initialize();
        auto it = postcodeMap.find(postcode);
        if (it != postcodeMap.end())
        {
            pfrPostcodeIface->set_property(postcodeStrProp, it->second);
        }
    }
}

void PfrPostcode::updatePostcode()
{
    if (pfrPostcodeIface && pfrPostcodeIface->is_initialized())
    {
        if (getPlatformState(postcode) < 0)
        {
            postcode = 0;
        }

        internalSet = true;
        pfrPostcodeIface->set_property(postcodeDataProp, postcode);
        auto it = postcodeMap.find(postcode);
        if (it == postcodeMap.end())
        {
            pfrPostcodeIface->set_property(postcodeStrProp, postcodeStrDefault);
        }
        else
        {
            pfrPostcodeIface->set_property(postcodeStrProp, it->second);
        }
        internalSet = false;
    }
    return;
}

} // namespace pfr
