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

#include <systemd/sd-journal.h>
#include <unistd.h>

#include <boost/asio.hpp>
#include <sdbusplus/asio/property.hpp>
#include <sdbusplus/unpack_properties.hpp>

namespace pfr
{

static bool i2cConfigLoaded = false;
static int retrCount = 10;

static bool stateTimerRunning = false;
bool bmcBootCompleteChkPointDone = false;
bool unProvChkPointStatus = false;
static constexpr uint8_t bmcBootFinishedChkPoint = 0x09;

std::unique_ptr<boost::asio::steady_timer> stateTimer = nullptr;
std::unique_ptr<boost::asio::steady_timer> initTimer = nullptr;
std::unique_ptr<boost::asio::steady_timer> pfrObjTimer = nullptr;
std::vector<std::unique_ptr<PfrVersion>> pfrVersionObjects;
std::unique_ptr<PfrConfig> pfrConfigObject;
std::unique_ptr<PfrPostcode> pfrPostcodeObject;

// List holds <ObjPath> <ImageType> <VersionPurpose>
static std::vector<std::tuple<std::string, ImageType, std::string>>
    verComponentList = {
        std::make_tuple("bmc_recovery", ImageType::bmcRecovery,
                        versionPurposeBMC),
        std::make_tuple("bios_recovery", ImageType::biosRecovery,
                        versionPurposeHost),
        std::make_tuple("rot_fw_recovery", ImageType::cpldRecovery,
                        versionPurposeOther),
        std::make_tuple("afm_active", ImageType::afmActive,
                        versionPurposeOther),
        std::make_tuple("afm_recovery", ImageType::afmRecovery,
                        versionPurposeOther),
};

// Recovery reason map.
// {<CPLD association>,{<Redfish MessageID>, <Recovery Reason>}}
static const boost::container::flat_map<uint8_t,
                                        std::pair<std::string, std::string>>
    recoveryReasonMap = {
        {0x01,
         {"BIOSFirmwareRecoveryReason",
          "BIOS active image authentication failure"}},
        {0x02,
         {"BIOSFirmwareRecoveryReason",
          "BIOS recovery image authentication failure"}},
        {0x03, {"MEFirmwareRecoveryReason", "ME launch failure"}},
        {0x04, {"BIOSFirmwareRecoveryReason", "ACM launch failure"}},
        {0x05, {"BIOSFirmwareRecoveryReason", "IBB launch failure"}},
        {0x06, {"BIOSFirmwareRecoveryReason", "OBB launch failure"}},
        {0x07,
         {"BMCFirmwareRecoveryReason",
          "BMC active image authentication failure"}},
        {0x08,
         {"BMCFirmwareRecoveryReason",
          "BMC recovery image authentication failure"}},
        {0x09, {"BMCFirmwareRecoveryReason", "BMC launch failure"}},
        {0x0A, {"CPLDFirmwareRecoveryReason", "CPLD watchdog expired"}},
        {0x0B, {"BMCFirmwareRecoveryReason", "BMC attestation failure"}},
        {0x0C, {"FirmwareResiliencyError", "CPU0  attestation failure"}},
        {0x0D, {"FirmwareResiliencyError", "CPU1  attestation failure"}}};

// Panic Reason map.
// {<CPLD association>, {<Redfish MessageID>, <Panic reason> })
static const boost::container::flat_map<uint8_t,
                                        std::pair<std::string, std::string>>
    panicReasonMap = {
        {0x01, {"BIOSFirmwarePanicReason", "BIOS update intent"}},
        {0x02, {"BMCFirmwarePanicReason", "BMC update intent"}},
        {0x03, {"BMCFirmwarePanicReason", "BMC reset detected"}},
        {0x04, {"BMCFirmwarePanicReason", "BMC watchdog expired"}},
        {0x05, {"MEFirmwarePanicReason", "ME watchdog expired"}},
        {0x06, {"BIOSFirmwarePanicReason", "ACM/IBB/OBB WDT expired"}},
        {0x09,
         {"BIOSFirmwarePanicReason",
          "ACM or IBB or OBB authentication failure"}},
        {0x0A, {"FirmwareResiliencyError", "Attestation failure"}}};

// Firmware resiliency major map.
// {<CPLD association>, {<Redfish MessageID>, <Error reason> })
static const boost::container::flat_map<uint8_t,
                                        std::pair<std::string, std::string>>
    majorErrorCodeMap = {
        {0x01,
         {"BMCFirmwareResiliencyError", "BMC image authentication failed"}},
        {0x02,
         {"BIOSFirmwareResiliencyError", "BIOS image authentication failed"}},
        {0x03,
         {"BIOSFirmwareResiliencyError", "in-band and oob update failure"}},
        {0x04, {"BMCFirmwareResiliencyError", "Communication setup failed"}},
        {0x05,
         {"FirmwareResiliencyError",
          "Attestation measurement mismatch-Attestation failure"}},
        {0x06, {"FirmwareResiliencyError", "Attestation challenge timeout"}},
        {0x07, {"FirmwareResiliencyError", "SPDM protocol timeout"}},
        {0x08, {"FirmwareResiliencyError", "I2c Communication failure"}},
        {0x09,
         {"CPLDFirmwareResiliencyError",
          "Combined CPLD authentication failure"}},
        {0x0A, {"CPLDFirmwareResiliencyError", "Combined CPLD update failure"}},
        {0x0B,
         {"CPLDFirmwareResiliencyError", "Combined CPLD recovery failure"}},
        {0x10, {"FirmwareResiliencyError", "Image copy Failed"}}};

static void updateDbusPropertiesCache()
{
    for (const auto& pfrVerObj : pfrVersionObjects)
    {
        pfrVerObj->updateVersion();
    }

    // Update provisoningStatus properties
    pfrConfigObject->updateProvisioningStatus();

    phosphor::logging::log<phosphor::logging::level::INFO>(
        "PFR Manager service cache data updated.");
}

static void logLastRecoveryEvent()
{
    uint8_t reason = 0;
    if (0 != readCpldReg(ActionType::recoveryReason, reason))
    {
        return;
    }

    auto it = recoveryReasonMap.find(reason);
    if (it == recoveryReasonMap.end())
    {
        // No matching found. So just return without logging event.
        return;
    }
    std::string msgId = "OpenBMC.0.1." + it->second.first;
    sd_journal_send("MESSAGE=%s", "Platform firmware recovery occurred.",
                    "PRIORITY=%i", LOG_WARNING, "REDFISH_MESSAGE_ID=%s",
                    msgId.c_str(), "REDFISH_MESSAGE_ARGS=%s",
                    it->second.second.c_str(), NULL);
}

static void logLastPanicEvent()
{
    uint8_t reason = 0;
    if (0 != readCpldReg(ActionType::panicReason, reason))
    {
        return;
    }

    auto it = panicReasonMap.find(reason);
    if (it == panicReasonMap.end())
    {
        // No matching found. So just return without logging event.
        return;
    }

    std::string msgId = "OpenBMC.0.1." + it->second.first;
    sd_journal_send("MESSAGE=%s", "Platform firmware panic occurred.",
                    "PRIORITY=%i", LOG_WARNING, "REDFISH_MESSAGE_ID=%s",
                    msgId.c_str(), "REDFISH_MESSAGE_ARGS=%s",
                    it->second.second.c_str(), NULL);
}

static void logResiliencyErrorEvent(const uint8_t majorErrorCode,
                                    const uint8_t minorErrorCode)
{
    uint8_t cpldRoTRev = 0;
    if (0 != readCpldReg(ActionType::readRoTRev, cpldRoTRev))
    {
        return;
    }

    auto it = majorErrorCodeMap.find(majorErrorCode);
    if (cpldRoTRev == 0x02)
    {
        auto itRev2 = majorErrorCodeMapRev2.find(majorErrorCode);
        if (itRev2 != majorErrorCodeMapRev2.end())
        {
            it = itRev2;
        }
        else if (it == majorErrorCodeMap.end())
        {
            // No matching found. So just return without logging event.
            return;
        }
    }
    else if (it == majorErrorCodeMap.end())
    {
        // No matching found. So just return without logging event.
        return;
    }

    std::string errorStr = it->second.second + "(MinorCode:0x" +
                           toHexString(minorErrorCode) + ")";
    std::string msgId = "OpenBMC.0.1." + it->second.first;
    sd_journal_send(
        "MESSAGE=%s", "Platform firmware resiliency error occurred.",
        "PRIORITY=%i", LOG_ERR, "REDFISH_MESSAGE_ID=%s", msgId.c_str(),
        "REDFISH_MESSAGE_ARGS=%s", errorStr.c_str(), NULL);
}

static void
    handleLastCountChange(std::shared_ptr<sdbusplus::asio::connection> conn,
                          std::string eventName, uint8_t currentCount)
{
    sdbusplus::asio::setProperty(*conn, "xyz.openbmc_project.Settings",
                                 "/xyz/openbmc_project/pfr/last_events",
                                 "xyz.openbmc_project.PFR.LastEvents",
                                 eventName, currentCount,
                                 [](boost::system::error_code ec) {
        if (ec)
        {
            phosphor::logging::log<phosphor::logging::level::ERR>(
                "PFR: Unable to update currentCount",
                phosphor::logging::entry("MSG=%s", ec.message().c_str()));
            return;
        }
    });
    return;
}

static void
    checkAndLogEvents(std::shared_ptr<sdbusplus::asio::connection>& conn)
{
    sdbusplus::asio::getAllProperties(
        *conn, "xyz.openbmc_project.Settings",
        "/xyz/openbmc_project/pfr/last_events",
        "xyz.openbmc_project.PFR.LastEvents",
        [conn](
            boost::system::error_code ec,
            const std::vector<
                std::pair<std::string, std::variant<std::monostate, uint8_t>>>&
                properties) {
        if (ec)
        {
            phosphor::logging::log<phosphor::logging::level::ERR>(
                "PFR: Unable get PFR last events",
                phosphor::logging::entry("MSG=%s", ec.message().c_str()));
            return;
        }
        uint8_t lastRecoveryCount = 0;
        uint8_t lastPanicCount = 0;
        uint8_t lastMajorErr = 0;
        uint8_t lastMinorErr = 0;

        try
        {
            sdbusplus::unpackProperties(
                properties, "lastRecoveryCount", lastRecoveryCount,
                "lastPanicCount", lastPanicCount, "lastMajorErr", lastMajorErr,
                "lastMinorErr", lastMinorErr);
        }
        catch (const sdbusplus::exception::UnpackPropertyError& error)
        {
            phosphor::logging::log<phosphor::logging::level::ERR>(
                "PFR: Unpack error",
                phosphor::logging::entry("MSG=%s", error.what()));
            return;
        }

        uint8_t currPanicCount = 0;
        if (0 == readCpldReg(ActionType::panicCount, currPanicCount))
        {
            if (lastPanicCount != currPanicCount)
            {
                // Update cached data to dbus and log redfish
                // event by reading reason.
                handleLastCountChange(conn, "lastPanicCount", currPanicCount);
                if (currPanicCount)
                {
                    logLastPanicEvent();
                }
            }
        }

        uint8_t currRecoveryCount = 0;
        if (0 == readCpldReg(ActionType::recoveryCount, currRecoveryCount))
        {
            if (lastRecoveryCount != currRecoveryCount)
            {
                // Update cached data to dbus and log redfish
                // event by reading reason.
                handleLastCountChange(conn, "lastRecoveryCount",
                                      currRecoveryCount);
                if (currRecoveryCount)
                {
                    logLastRecoveryEvent();
                }
            }
        }

        uint8_t majorErr = 0;
        uint8_t minorErr = 0;
        if ((0 == readCpldReg(ActionType::majorError, majorErr)) &&
            (0 == readCpldReg(ActionType::minorError, minorErr)))
        {
            if ((lastMajorErr != majorErr) || (lastMinorErr != minorErr))
            {
                // Update cached data to dbus and log redfish event by
                // reading reason.
                handleLastCountChange(conn, "lastMajorErr", majorErr);
                handleLastCountChange(conn, "lastMinorErr", minorErr);
                if (majorErr && minorErr)
                {
                    logResiliencyErrorEvent(majorErr, minorErr);
                }
            }
        }
    });
}

static void monitorPlatformStateChange(
    sdbusplus::asio::object_server& server,
    std::shared_ptr<sdbusplus::asio::connection>& conn)
{
    constexpr size_t pollTimeout = 10; // seconds
    stateTimer->expires_after(std::chrono::seconds(pollTimeout));
    stateTimer->async_wait(
        [&server, &conn](const boost::system::error_code& ec) {
        if (ec == boost::asio::error::operation_aborted)
        {
            // Timer reset.
            return;
        }
        if (ec)
        {
            // Platform State Monitor - Timer cancelled.
            return;
        }
        checkAndLogEvents(conn);
        monitorPlatformStateChange(server, conn);
    });
}

void checkAndSetCheckpoint(sdbusplus::asio::object_server& server,
                           std::shared_ptr<sdbusplus::asio::connection>& conn)
{
    // Check whether systemd completed all the loading.
    conn->async_method_call(
        [&server, &conn](boost::system::error_code ec,
                         const std::variant<uint64_t>& value) {
        if (!ec)
        {
            if (std::get<uint64_t>(value))
            {
                phosphor::logging::log<phosphor::logging::level::INFO>(
                    "BMC boot completed. Setting checkpoint 9.");
                if (!bmcBootCompleteChkPointDone)
                {
                    setBMCBootCompleteChkPoint(bmcBootFinishedChkPoint);
                }
                return;
            }
        }
        else
        {
            // Failed to get data from systemd. System might not
            // be ready yet. Attempt again for data.
            phosphor::logging::log<phosphor::logging::level::ERR>(
                "aync call failed to get FinishTimestamp.",
                phosphor::logging::entry("MSG=%s", ec.message().c_str()));
        }
        // FIX-ME: Latest up-stream sync caused issue in receiving
        // StartupFinished signal. Unable to get StartupFinished signal
        // from systemd1 hence using poll method too, to trigger it
        // properly.
        constexpr size_t pollTimeout = 10; // seconds
        initTimer->expires_after(std::chrono::seconds(pollTimeout));
        initTimer->async_wait(
            [&server, &conn](const boost::system::error_code& ec) {
            if (ec == boost::asio::error::operation_aborted)
            {
                // Timer reset.
                phosphor::logging::log<phosphor::logging::level::INFO>(
                    "Set boot Checkpoint - Timer aborted or stopped.");
                return;
            }
            if (ec)
            {
                phosphor::logging::log<phosphor::logging::level::ERR>(
                    "Set boot Checkpoint - async wait error.");
                return;
            }
            checkAndSetCheckpoint(server, conn);
        });
    },
        "org.freedesktop.systemd1", "/org/freedesktop/systemd1",
        "org.freedesktop.DBus.Properties", "Get",
        "org.freedesktop.systemd1.Manager", "FinishTimestamp");
}

void monitorSignals(sdbusplus::asio::object_server& server,
                    std::shared_ptr<sdbusplus::asio::connection>& conn)
{
    // Monitor Boot finished signal and set the checkpoint 9 to
    // notify CPLD about BMC boot finish.
    auto bootFinishedSignal = std::make_unique<sdbusplus::bus::match_t>(
        static_cast<sdbusplus::bus_t&>(*conn),
        "type='signal',"
        "member='StartupFinished',path='/org/freedesktop/systemd1',"
        "interface='org.freedesktop.systemd1.Manager'",
        [&server, &conn](sdbusplus::message_t& msg) {
        if (!bmcBootCompleteChkPointDone)
        {
            phosphor::logging::log<phosphor::logging::level::INFO>(
                "BMC boot completed(StartupFinished). Setting "
                "checkpoint 9.");
            setBMCBootCompleteChkPoint(bmcBootFinishedChkPoint);
        }
    });
    checkAndSetCheckpoint(server, conn);

    // Capture the Chassis state and Start the monitor timer
    // if state changed to 'On'. Run timer until  OS boot.
    // Stop timer if state changed to 'Off'.
    static auto matchChassisState = sdbusplus::bus::match_t(
        static_cast<sdbusplus::bus_t&>(*conn),
        "type='signal',member='PropertiesChanged', "
        "interface='org.freedesktop.DBus.Properties', "
        "sender='xyz.openbmc_project.State.Chassis', "
        "arg0namespace='xyz.openbmc_project.State.Chassis'",
        [&server, &conn](sdbusplus::message_t& message) {
        std::string intfName;
        std::map<std::string, std::variant<std::string>> properties;
        message.read(intfName, properties);

        const auto it = properties.find("CurrentPowerState");
        if (it != properties.end())
        {
            const std::string* state = std::get_if<std::string>(&it->second);
            if (state != nullptr)
            {
                if ((*state ==
                     "xyz.openbmc_project.State.Chassis.PowerState.On") &&
                    (!stateTimerRunning))
                {
                    stateTimerRunning = true;
                    monitorPlatformStateChange(server, conn);
                }
                else if ((*state == "xyz.openbmc_project.State.Chassis."
                                    "PowerState.Off") &&
                         (stateTimerRunning))
                {
                    stateTimer->cancel();
                    checkAndLogEvents(conn);
                    stateTimerRunning = false;
                }
            }

            // Update the D-Bus properties when chassis state changes.
            updateDbusPropertiesCache();
        }
    });

    // Capture the Host state and Start the monitor timer
    // if state changed to 'Running'. Run timer until OS boot.
    // Stop timer if state changed to 'Off'.
    static auto matchHostState = sdbusplus::bus::match_t(
        static_cast<sdbusplus::bus_t&>(*conn),
        "type='signal',member='PropertiesChanged', "
        "interface='org.freedesktop.DBus.Properties', "
        "sender='xyz.openbmc_project.State.Chassis', "
        "arg0namespace='xyz.openbmc_project.State.Host'",
        [&server, &conn](sdbusplus::message_t& message) {
        std::string intfName;
        std::map<std::string, std::variant<std::string>> properties;
        message.read(intfName, properties);

        const auto it = properties.find("CurrentHostState");
        if (it != properties.end())
        {
            const std::string* state = std::get_if<std::string>(&it->second);
            if (state != nullptr)
            {
                if ((*state ==
                     "xyz.openbmc_project.State.Host.HostState.Running") &&
                    (!stateTimerRunning))
                {
                    stateTimerRunning = true;
                    monitorPlatformStateChange(server, conn);
                }
                else if (((*state == "xyz.openbmc_project.State.Host."
                                     "HostState.Off") ||
                          (*state == "xyz.openbmc_project.State.Host."
                                     "HostState.Quiesced")) &&
                         (stateTimerRunning))
                {
                    stateTimer->cancel();
                    checkAndLogEvents(conn);
                    stateTimerRunning = false;
                }
            }

            // Update the D-Bus properties when host state changes.
            updateDbusPropertiesCache();
        }
    });

    // Capture the OS state change and stop monitor timer
    // if OS boots completly or becomes Inactive.
    // start timer in other cases to mnitor states.
    static auto matchOsState = sdbusplus::bus::match_t(
        static_cast<sdbusplus::bus_t&>(*conn),
        "type='signal',member='PropertiesChanged', "
        "interface='org.freedesktop.DBus.Properties', "
        "sender='xyz.openbmc_project.State.Chassis', "
        "arg0namespace='xyz.openbmc_project.State.OperatingSystem.Status'",
        [&server, &conn](sdbusplus::message_t& message) {
        std::string intfName;
        std::map<std::string, std::variant<std::string>> properties;
        message.read(intfName, properties);

        const auto it = properties.find("OperatingSystemState");
        if (it != properties.end())
        {
            const std::string* state = std::get_if<std::string>(&it->second);
            if (state != nullptr)
            {
                // The short strings "BootComplete" and "Standby" are
                // deprecated in favor of the full enum strings
                // Support for the short strings will be removed in the
                // future.
                if (((*state == "BootComplete") ||
                     (*state == "xyz.openbmc_project.State.OperatingSystem."
                                "Status.OSStatus.BootComplete") ||
                     (*state == "Inactive") ||
                     (*state == "xyz.openbmc_project.State.OperatingSystem."
                                "Status.OSStatus.Inactive")) &&
                    (stateTimerRunning))
                {
                    stateTimer->cancel();
                    checkAndLogEvents(conn);
                    stateTimerRunning = false;
                }
                else if (!stateTimerRunning)
                {
                    stateTimerRunning = true;
                    monitorPlatformStateChange(server, conn);
                }
            }
        }
    });

    // First time, check and log events if any.
    checkAndLogEvents(conn);
}

static void updateCPLDversion(std::shared_ptr<sdbusplus::asio::connection> conn)
{
    std::string cpldVersion = pfr::readCPLDVersion();
    lg2::info("VERSION INFO - rot_fw_active - {VER}", "VER", cpldVersion);
    conn->async_method_call(
        [](const boost::system::error_code ec) {
        if (ec)
        {
            phosphor::logging::log<phosphor::logging::level::ERR>(
                "Unable to update rot_fw_active version",
                phosphor::logging::entry("MSG=%s", ec.message().c_str()));
            return;
        }
    },
        "xyz.openbmc_project.Settings",
        "/xyz/openbmc_project/software/rot_fw_active",
        "org.freedesktop.DBus.Properties", "Set",
        "xyz.openbmc_project.Software.Version", "Version",
        std::variant<std::string>(cpldVersion));
    return;
}

void checkPfrInterface(std::shared_ptr<sdbusplus::asio::connection> conn,
                       sdbusplus::asio::object_server& server)
{
    if (!i2cConfigLoaded)
    {
        init(conn, i2cConfigLoaded);
        if (retrCount > 0)
        {
            // pfr object not loaded yet. query again.
            return;
        }
        else
        {
            // Platform does not contain pfr object. Stop the service.
            phosphor::logging::log<phosphor::logging::level::INFO>(
                "Platform does not support PFR, hence stop the "
                "service.");
            std::exit(EXIT_SUCCESS);
            return;
        }
    }
    else
    {
        retrCount = 0;

        bool locked = false;
        bool prov = false;
        bool support = false;
        pfr::getProvisioningStatus(locked, prov, support);
        if (support && prov)
        {
            // pfr provisioned.
            phosphor::logging::log<phosphor::logging::level::INFO>(
                "PFR Supported.");
            return;
        }
        else
        {
            unProvChkPointStatus = true;
            pfr::monitorSignals(server, conn);
        }
    }
}
void checkPFRandAddObjects(sdbusplus::asio::object_server& server,
                           std::shared_ptr<sdbusplus::asio::connection>& conn)
{
    checkPfrInterface(conn, server);

    constexpr size_t timeout = 10; // seconds
    pfrObjTimer->expires_after(std::chrono::seconds(timeout));
    pfrObjTimer->async_wait(
        [&conn, &server](const boost::system::error_code& ec) {
        if (ec)
        {
            if (ec == boost::asio::error::operation_aborted)
            {
                // Timer reset.
                phosphor::logging::log<phosphor::logging::level::INFO>(
                    "pfr object found. Hence Object Timer aborted or stopped.");
            }
            else
            {
                phosphor::logging::log<phosphor::logging::level::ERR>(
                    "pfr object timer error.");
            }
        }
        if (retrCount > 0)
        {
            checkPFRandAddObjects(server, conn);
        }
        else
        {
            pfr::monitorSignals(server, conn);

            // Update the D-Bus properties.
            updateDbusPropertiesCache();
            // Update CPLD Version to rot_fw_active object in settings.
            updateCPLDversion(conn);
        }
        retrCount--;
    });
}
} // namespace pfr

int main()
{
    // setup connection to dbus
    boost::asio::io_service io;
    auto conn = std::make_shared<sdbusplus::asio::connection>(io);
    pfr::stateTimer = std::make_unique<boost::asio::steady_timer>(io);
    pfr::initTimer = std::make_unique<boost::asio::steady_timer>(io);
    pfr::pfrObjTimer = std::make_unique<boost::asio::steady_timer>(io);
    auto server = sdbusplus::asio::object_server(conn, true);
    pfr::init(conn, pfr::i2cConfigLoaded);

    pfr::checkPFRandAddObjects(server, conn);

    // Update CPLD Version to rot_fw_active object in settings.
    pfr::updateCPLDversion(conn);

    server.add_manager("/xyz/openbmc_project/pfr");

    // Create PFR attributes object and interface
    pfr::pfrConfigObject = std::make_unique<pfr::PfrConfig>(server, conn);

    // Create Software objects using Versions interface
    for (const auto& entry : pfr::verComponentList)
    {
        pfr::pfrVersionObjects.emplace_back(std::make_unique<pfr::PfrVersion>(
            server, conn, std::get<0>(entry), std::get<1>(entry),
            std::get<2>(entry)));
    }

    if (pfr::pfrConfigObject)
    {
        pfr::pfrConfigObject->updateProvisioningStatus();
        if (pfr::pfrConfigObject->getPfrProvisioned())
        {
            pfr::pfrPostcodeObject = std::make_unique<pfr::PfrPostcode>(server,
                                                                        conn);
        }
    }

    conn->request_name("xyz.openbmc_project.PFR.Manager");
    phosphor::logging::log<phosphor::logging::level::INFO>(
        "Intel PFR service started successfully");
    io.run();

    return 0;
}
