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

#include <gpiod.hpp>

#include <iomanip>
#include <iostream>
#include <sstream>

namespace pfr
{

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

static int i2cBusNumber = 4;
static int i2cSlaveAddress = 56;

// CPLD mailbox registers
static constexpr uint8_t pfrROTId = 0x00;
static constexpr uint8_t cpldROTVersion = 0x01;
static constexpr uint8_t cpldROTSvn = 0x02;
static constexpr uint8_t platformState = 0x03;
static constexpr uint8_t recoveryCount = 0x04;
static constexpr uint8_t lastRecoveryReason = 0x05;
static constexpr uint8_t panicEventCount = 0x06;
static constexpr uint8_t panicEventReason = 0x07;
static constexpr uint8_t majorErrorCode = 0x08;
static constexpr uint8_t minorErrorCode = 0x09;
static constexpr uint8_t provisioningStatus = 0x0A;
static constexpr uint8_t bmcBootCheckpointRev1 = 0x0F;
static constexpr uint8_t bmcBootCheckpoint = 0x60;
static constexpr uint8_t pchActiveMajorVersion = 0x15;
static constexpr uint8_t pchActiveMinorVersion = 0x16;
static constexpr uint8_t pchRecoveryMajorVersion = 0x1B;
static constexpr uint8_t pchRecoveryMinorVersion = 0x1C;
static constexpr uint8_t CPLDHashRegStart = 0x20;
static constexpr uint8_t pfrRoTValue = 0xDE;
static constexpr uint8_t afmActiveMajorVersion = 0x75;
static constexpr uint8_t afmActiveMinorVersion = 0x76;
static constexpr uint8_t afmRecoveryMajorVersion = 0x78;
static constexpr uint8_t afmRecoveryMinorVersion = 0x79;

static constexpr uint8_t ufmLockedMask = (0x1 << 0x04);
static constexpr uint8_t ufmProvisionedMask = (0x1 << 0x05);

// PFR MTD devices
static constexpr const char* bmcActiveImgPfmMTDDev = "/dev/mtd/pfm";
static constexpr const char* bmcRecoveryImgMTDDev = "/dev/mtd/rc-image";

// PFM offset in full image
static constexpr const uint32_t pfmBaseOffsetInImage = 0x400;

// OFFSET values in PFM
static constexpr const uint32_t verOffsetInPFM = 0x406;
static constexpr const uint32_t buildNumOffsetInPFM = 0x40C;
static constexpr const uint32_t buildHashOffsetInPFM = 0x40D;

bool exceptionFlag = true;
extern bool bmcBootCompleteChkPointDone;
extern bool unProvChkPointStatus;

void init(std::shared_ptr<sdbusplus::asio::connection> conn,
          bool& i2cConfigLoaded)
{
    conn->async_method_call(
        [conn, &i2cConfigLoaded](const boost::system::error_code ec,
                                 const GetSubTreeType& resp) {
            if (ec || resp.size() != 1)
            {
                return;
            }
            if (resp[0].second.begin() == resp[0].second.end())
                return;
            const std::string& objPath = resp[0].first;
            const std::string& serviceName = resp[0].second.begin()->first;

            const std::string match = "Baseboard/PFR";
            if (boost::ends_with(objPath, match))
            {
                // PFR object found.. check for PFR support
                conn->async_method_call(
                    [objPath, serviceName, conn, &i2cConfigLoaded](
                        boost::system::error_code ec,
                        const std::vector<std::pair<
                            std::string, std::variant<std::string, uint64_t>>>&
                            propertiesList) {
                        if (ec)
                        {
                            phosphor::logging::log<
                                phosphor::logging::level::ERR>(
                                "Error to Get PFR properties.",
                                phosphor::logging::entry("MSG=%s",
                                                         ec.message().c_str()));
                            return;
                        }

                        const uint64_t* i2cBus = nullptr;
                        const uint64_t* address = nullptr;

                        for (const auto& [propName, propVariant] :
                             propertiesList)
                        {
                            if (propName == "Address")
                            {
                                address = std::get_if<uint64_t>(&propVariant);
                            }
                            else if (propName == "Bus")
                            {
                                i2cBus = std::get_if<uint64_t>(&propVariant);
                            }
                        }

                        if ((address == nullptr) || (i2cBus == nullptr))
                        {
                            phosphor::logging::log<
                                phosphor::logging::level::ERR>(
                                "Unable to read the pfr properties");
                            return;
                        }

                        i2cBusNumber = static_cast<int>(*i2cBus);
                        i2cSlaveAddress = static_cast<int>(*address);
                        i2cConfigLoaded = true;
                    },
                    serviceName, objPath, "org.freedesktop.DBus.Properties",
                    "GetAll", "xyz.openbmc_project.Configuration.PFR");
            }
        },
        "xyz.openbmc_project.ObjectMapper",
        "/xyz/openbmc_project/object_mapper",
        "xyz.openbmc_project.ObjectMapper", "GetSubTree",
        "/xyz/openbmc_project/inventory/system", 0,
        std::array<const char*, 1>{"xyz.openbmc_project.Configuration.PFR"});
    return;
}

std::string toHexString(const uint8_t val)
{
    std::stringstream stream;
    stream << std::setfill('0') << std::setw(2) << std::hex
           << static_cast<int>(val);
    return stream.str();
}

static std::string readCPLDHash()
{
    std::stringstream hashStrStream;
    static constexpr uint8_t hashLength = 32;
    std::array<uint8_t, hashLength> hashValue = {0};
    try
    {
        I2CFile cpldDev(i2cBusNumber, i2cSlaveAddress, O_RDWR | O_CLOEXEC);
        if (cpldDev.i2cReadBlockData(CPLDHashRegStart, hashLength,
                                     hashValue.data()))
        {
            for (const auto& i : hashValue)
            {
                hashStrStream << std::setfill('0') << std::setw(2) << std::hex
                              << static_cast<int>(i);
            }
        }
        else
        {
            // read failed
            phosphor::logging::log<phosphor::logging::level::ERR>(
                "Failed to read CPLD Hash string");
            return "";
        }
    }
    catch (const std::exception& e)
    {
        phosphor::logging::log<phosphor::logging::level::ERR>(
            "Exception caught in readCPLDHash.",
            phosphor::logging::entry("MSG=%s", e.what()));
        return "";
    }
    return hashStrStream.str();
}

static std::string readVersionFromCPLD(const uint8_t majorReg,
                                       const uint8_t minorReg)
{
    try
    {
        I2CFile cpldDev(i2cBusNumber, i2cSlaveAddress, O_RDWR | O_CLOEXEC);
        uint8_t majorVer = cpldDev.i2cReadByteData(majorReg);
        uint8_t minorVer = cpldDev.i2cReadByteData(minorReg);
        // Major and Minor versions should be binary encoded strings.
        std::string version =
            std::to_string(majorVer) + "." + std::to_string(minorVer);
        return version;
    }
    catch (const std::exception& e)
    {
        phosphor::logging::log<phosphor::logging::level::ERR>(
            "Exception caught in readVersionFromCPLD.",
            phosphor::logging::entry("MSG=%s", e.what()));
        return "";
    }
}

static std::string readBMCVersionFromSPI(const ImageType& imgType)
{
    std::string mtdDev;
    uint32_t verOffset = verOffsetInPFM;
    uint32_t bldNumOffset = buildNumOffsetInPFM;
    uint32_t bldHashOffset = buildHashOffsetInPFM;

    if (imgType == ImageType::bmcActive)
    {
        // For Active image, PFM is emulated as separate MTD device.
        mtdDev = bmcActiveImgPfmMTDDev;
    }
    else if (imgType == ImageType::bmcRecovery)
    {
        // For Recovery image, PFM is part of compressed Image
        // at offset 0x400.
        mtdDev = bmcRecoveryImgMTDDev;
        verOffset += pfmBaseOffsetInImage;
        bldNumOffset += pfmBaseOffsetInImage;
        bldHashOffset += pfmBaseOffsetInImage;
    }
    else
    {
        phosphor::logging::log<phosphor::logging::level::ERR>(
            "Invalid image type passed to readBMCVersionFromSPI.");
        return "";
    }

    uint8_t buildNo = 0;
    std::array<uint8_t, 2> ver;
    std::array<uint8_t, 3> buildHash;

    try
    {
        SPIDev spiDev(mtdDev);
        spiDev.spiReadData(verOffset, ver.size(),
                           reinterpret_cast<void*>(ver.data()));
        spiDev.spiReadData(bldNumOffset, sizeof(buildNo),
                           reinterpret_cast<void*>(&buildNo));
        spiDev.spiReadData(bldHashOffset, buildHash.size(),
                           reinterpret_cast<void*>(buildHash.data()));
    }
    catch (const std::exception& e)
    {
        phosphor::logging::log<phosphor::logging::level::ERR>(
            "Exception caught in readBMCVersionFromSPI.",
            phosphor::logging::entry("MSG=%s", e.what()));
        return "";
    }

    // Version format: <major>.<minor>-<build bum>-g<build hash>
    // Example: 0.11-7-g1e5c2d
    // Major, minor and build numberare BCD encoded.
    std::string version =
        std::to_string(ver[0]) + "." + std::to_string(ver[1]) + "-" +
        std::to_string(buildNo) + "-g" + toHexString(buildHash[0]) +
        toHexString(buildHash[1]) + toHexString(buildHash[2]);
    return version;
}

static bool getGPIOInput(const std::string& name, gpiod::line& gpioLine,
                         uint8_t* value)
{
    // Find the GPIO line
    gpioLine = gpiod::find_line(name);
    if (!gpioLine)
    {
        phosphor::logging::log<phosphor::logging::level::ERR>(
            "Failed to find the GPIO line: ",
            phosphor::logging::entry("MSG=%s", name.c_str()));
        return false;
    }
    try
    {
        gpioLine.request({__FUNCTION__, gpiod::line_request::DIRECTION_INPUT});
    }
    catch (const std::exception& e)
    {
        phosphor::logging::log<phosphor::logging::level::ERR>(
            "Failed to request the GPIO line",
            phosphor::logging::entry("MSG=%s", e.what()));
        gpioLine.release();
        return false;
    }
    try
    {
        *value = gpioLine.get_value();
    }
    catch (const std::exception& e)
    {
        phosphor::logging::log<phosphor::logging::level::ERR>(
            "Failed to get the value of GPIO line",
            phosphor::logging::entry("MSG=%s", e.what()));
        gpioLine.release();
        return false;
    }
    gpioLine.release();
    return true;
}

std::string readCPLDVersion()
{
    std::string svnRoTHash = "";
    std::string version = "unknown";

    // check if reg 0x00 read 0xde
    uint8_t cpldRoTValue = 0;
    try
    {
        I2CFile cpldDev(i2cBusNumber, i2cSlaveAddress, O_RDWR | O_CLOEXEC);
        cpldRoTValue = cpldDev.i2cReadByteData(pfrROTId);
    }
    catch (const std::exception& e)
    {
        phosphor::logging::log<phosphor::logging::level::ERR>(
            "Exception caught in readCPLDVersion.",
            phosphor::logging::entry("MSG=%s", e.what()));
    }

    if (cpldRoTValue == pfrRoTValue)
    {
        // read RoT Rev and RoT SVN
        std::string rotRevSVN = readVersionFromCPLD(cpldROTVersion, cpldROTSvn);

        // read CPLD hash
        std::string cpldHash = readCPLDHash();
        version = rotRevSVN + "-" + cpldHash;
    }
    else
    {
        phosphor::logging::log<phosphor::logging::level::INFO>(
            "PFR-CPLD not present.");
    }

    // ROT FW Version format:
    // When PFR CPLD is present
    // <RoTRev.RoTSVN>-<RoT HASH>
    // Example: 3.0-<Hash string>

    return version;
}

std::string getFirmwareVersion(const ImageType& imgType)
{
    switch (imgType)
    {
        case (ImageType::cpldActive):
        {
            return readCPLDVersion();
        }
        case (ImageType::cpldRecovery):
        {
            // TO-DO: Need to update once CPLD supported Firmware is available
            return readVersionFromCPLD(cpldROTVersion, cpldROTSvn);
        }
        case (ImageType::biosActive):
        {
            return readVersionFromCPLD(pchActiveMajorVersion,
                                       pchActiveMinorVersion);
        }
        case (ImageType::biosRecovery):
        {
            return readVersionFromCPLD(pchRecoveryMajorVersion,
                                       pchRecoveryMinorVersion);
        }
        case (ImageType::bmcActive):
        case (ImageType::bmcRecovery):
        {
            return readBMCVersionFromSPI(imgType);
        }
        case (ImageType::afmActive):
        {
            return readVersionFromCPLD(afmActiveMajorVersion,
                                       afmActiveMinorVersion);
        }
        case (ImageType::afmRecovery):
        {
            return readVersionFromCPLD(afmRecoveryMajorVersion,
                                       afmRecoveryMinorVersion);
        }
        default:
            // Invalid image Type.
            return "";
    }
}

int getProvisioningStatus(bool& ufmLocked, bool& ufmProvisioned,
                          bool& ufmSupport)
{
    try
    {
        I2CFile cpldDev(i2cBusNumber, i2cSlaveAddress, O_RDWR | O_CLOEXEC);
        uint8_t provStatus = cpldDev.i2cReadByteData(provisioningStatus);
        uint8_t pfrRoT = cpldDev.i2cReadByteData(pfrROTId);
        ufmLocked = (provStatus & ufmLockedMask);
        ufmProvisioned = (provStatus & ufmProvisionedMask);
        ufmSupport = (pfrRoT & pfrRoTValue);
        return 0;
    }
    catch (const std::exception& e)
    {
        phosphor::logging::log<phosphor::logging::level::ERR>(
            "Exception caught in getProvisioningStatus.",
            phosphor::logging::entry("MSG=%s", e.what()));
        return -1;
    }
}

int getPlatformState(uint8_t& state)
{
    try
    {
        I2CFile cpldDev(i2cBusNumber, i2cSlaveAddress, O_RDWR | O_CLOEXEC);
        state = cpldDev.i2cReadByteData(platformState);

        return 0;
    }
    catch (const std::exception& e)
    {
        phosphor::logging::log<phosphor::logging::level::ERR>(
            "Exception caught in getPlatformState.",
            phosphor::logging::entry("MSG=%s", e.what()));
        return -1;
    }
}

int readCpldReg(const ActionType& action, uint8_t& value)
{
    uint8_t cpldReg;

    switch (action)
    {
        case (ActionType::readRoTRev):
            cpldReg = cpldROTVersion;
            break;
        case (ActionType::recoveryCount):
            cpldReg = recoveryCount;
            break;
        case (ActionType::recoveryReason):
            cpldReg = lastRecoveryReason;
            break;
        case (ActionType::panicCount):
            cpldReg = panicEventCount;
            break;
        case (ActionType::panicReason):
            cpldReg = panicEventReason;
            break;
        case (ActionType::majorError):
            cpldReg = majorErrorCode;
            break;
        case (ActionType::minorError):
            cpldReg = minorErrorCode;
            break;

        default:
            phosphor::logging::log<phosphor::logging::level::ERR>(
                "Invalid CPLD read action.");
            return -1;
    }

    try
    {
        I2CFile cpldDev(i2cBusNumber, i2cSlaveAddress, O_RDWR | O_CLOEXEC);
        value = cpldDev.i2cReadByteData(cpldReg);
        return 0;
    }
    catch (const std::exception& e)
    {
        if (exceptionFlag)
        {
            exceptionFlag = false;
            phosphor::logging::log<phosphor::logging::level::ERR>(
                "Exception caught in readCpldReg.",
                phosphor::logging::entry("MSG=%s", e.what()));
        }
        return -1;
    }
}

int setBMCBootCompleteChkPoint(const uint8_t checkPoint)
{
    uint8_t bmcBootCheckpointReg = bmcBootCheckpoint;

    // check if reg 0x01(RoTRev) is 1 or 2.
    // checkpoint register changes for RoT Rev 1 and 2
    uint8_t cpldRoTRev = 0;
    try
    {
        I2CFile cpldDev(i2cBusNumber, i2cSlaveAddress, O_RDWR | O_CLOEXEC);
        cpldRoTRev = cpldDev.i2cReadByteData(cpldROTVersion);
    }
    catch (const std::exception& e)
    {
        phosphor::logging::log<phosphor::logging::level::ERR>(
            "Exception caught in reading RoT rev.",
            phosphor::logging::entry("MSG=%s", e.what()));
        return -1;
    }

    // latest PFR has different check point register
    if (cpldRoTRev <= 1)
    {
        bmcBootCheckpointReg = bmcBootCheckpointRev1;
    }

    try
    {
        I2CFile cpldDev(i2cBusNumber, i2cSlaveAddress, O_RDWR | O_CLOEXEC);
        cpldDev.i2cWriteByteData(bmcBootCheckpointReg, checkPoint);
        phosphor::logging::log<phosphor::logging::level::INFO>(
            "Successfully set the PFR CPLD checkpoint 9.");
        bmcBootCompleteChkPointDone = true;
        if (unProvChkPointStatus)
        {
            unProvChkPointStatus = false;
            phosphor::logging::log<phosphor::logging::level::INFO>(
                "PFR is not provisioned, hence exit the service.");
            std::exit(EXIT_SUCCESS);
        }
        return 0;
    }
    catch (const std::exception& e)
    {
        phosphor::logging::log<phosphor::logging::level::ERR>(
            "Exception caught in setBMCBootCheckout.",
            phosphor::logging::entry("MSG=%s", e.what()));
        return -1;
    }
}

static bool setMBRegister(uint32_t regOffset, uint8_t regValue)
{
    try
    {
        I2CFile mailDev(i2cBusNumber, i2cSlaveAddress, O_RDWR | O_CLOEXEC);
        mailDev.i2cWriteByteData(regOffset, regValue);
        return true;
    }
    catch (const std::exception& e)
    {
        phosphor::logging::log<phosphor::logging::level::ERR>(
            "Exception caught in setting PFR Mailbox.",
            phosphor::logging::entry("MSG=%s", e.what()));
        return false;
    }
}

int setBMCBusy(bool setValue)
{
    uint32_t bmcBusyReg = 0x63;
    uint8_t valHigh = 0x80;
    uint8_t mailBoxReply = 0;

    if (getMBRegister(bmcBusyReg, mailBoxReply))
    {
        return -1;
    }
    uint8_t readValue = mailBoxReply | valHigh;
    if (setValue == false)
    {
        readValue &= 0b01111111;
    }
    if (!setMBRegister(bmcBusyReg, readValue))
    {
        return -1;
    }
    if (setValue == false)
    {
        phosphor::logging::log<phosphor::logging::level::DEBUG>(
            "Successfully reset the PFR MailBox register.");
    }
    else
    {
        phosphor::logging::log<phosphor::logging::level::DEBUG>(
            "Successfully set the PFR MailBox to BMCBusy.");
    }
    return 0;
}

int getMBRegister(uint32_t regAddr, uint8_t& mailBoxReply)
{
    // Read from PFR CPLD's mailbox register
    try
    {
        I2CFile mailReadDev(i2cBusNumber, i2cSlaveAddress, O_RDWR | O_CLOEXEC);

        mailBoxReply = mailReadDev.i2cReadByteData(regAddr);
    }
    catch (const std::exception& e)
    {
        phosphor::logging::log<phosphor::logging::level::ERR>(
            "Exception caught in mailbox reading.",
            phosphor::logging::entry("MSG=%s", e.what()));
        throw;
    }
    return 0;
}

} // namespace pfr
