#include "mp5998.hpp"

#include "common/include/utils.hpp"

#include <phosphor-logging/lg2.hpp>

#include <fstream>

PHOSPHOR_LOG2_USING;

namespace phosphor::software::VR
{

static constexpr std::string_view crcUserRegName = "CRC_USER";
static constexpr uint8_t eepromFaultBit = 0x01;
static constexpr uint8_t unlockData = 0x00;
static constexpr size_t statusByteLength = 1;

enum class MP5998Cmd : uint8_t
{
    crcUser = 0xF8,
    passwordReg = 0x0E,
};

sdbusplus::async::task<bool> MP5998::parseDeviceConfiguration()
{
    if (!configuration)
    {
        error("Device configuration not initialized");
        co_return false;
    }

    configuration->vendorId = 0x4D5053;
    configuration->productId = 0x35393938;

    for (const auto& tokens : parser->lineTokens)
    {
        if (!parser->isValidDataTokens(tokens))
        {
            continue;
        }

        auto regName = parser->getVal<std::string>(tokens, ATE::regName);

        if (regName == crcUserRegName)
        {
            configuration->configId =
                parser->getVal<uint32_t>(tokens, ATE::configId);
            configuration->crcUser =
                parser->getVal<uint32_t>(tokens, ATE::regDataHex);
        }
    }

    co_return true;
}

sdbusplus::async::task<bool> MP5998::verifyImage(const uint8_t* image,
                                                 size_t imageSize)
{
    if (!co_await parseImage(image, imageSize))
    {
        error("Image verification failed: image parsing failed");
        co_return false;
    }

    if (configuration->registersData.empty())
    {
        error("Image verification failed - no register data found");
        co_return false;
    }

    if (configuration->configId == 0)
    {
        error("Image verification failed - missing config ID");
        co_return false;
    }

    co_return true;
}

sdbusplus::async::task<bool> MP5998::checkId(PMBusCmd idCmd, uint32_t expected)
{
    static constexpr size_t mfrIdLength = 3;
    static constexpr size_t mfrModelLength = 5;

    std::vector<uint8_t> tbuf;
    std::vector<uint8_t> rbuf;

    tbuf = buildByteVector(PMBusCmd::page, MPSPage::page0);
    if (!i2cInterface.sendReceive(tbuf, rbuf))
    {
        error("MP5998: Failed to set page 0 for ID check");
        co_return false;
    }

    size_t bufferSize = 0;

    if (idCmd == PMBusCmd::mfrId)
    {
        bufferSize = statusByteLength + mfrIdLength;
    }
    else if (idCmd == PMBusCmd::mfrModel)
    {
        bufferSize = statusByteLength + mfrModelLength;
    }
    else
    {
        error("MP5998: Unsupported ID command: 0x{CMD}", "CMD", lg2::hex,
              static_cast<uint8_t>(idCmd));
        co_return false;
    }

    tbuf = buildByteVector(idCmd);
    rbuf.resize(bufferSize);

    if (!i2cInterface.sendReceive(tbuf, rbuf))
    {
        error("MP5998: I2C sendReceive failed for command 0x{CMD}", "CMD",
              lg2::hex, static_cast<uint8_t>(idCmd));
        co_return false;
    }

    auto idBytes = std::span(rbuf).subspan(statusByteLength);
    uint32_t id;
    if (idCmd == PMBusCmd::mfrModel)
    {
        auto productBytes = idBytes.subspan(1, 4);
        id = bytesToInt<uint32_t>(productBytes);
    }
    else
    {
        id = bytesToInt<uint32_t>(idBytes);
    }

    debug("Check ID cmd {CMD}: Got={ID}, Expected={EXP}", "CMD", lg2::hex,
          static_cast<uint8_t>(idCmd), "ID", lg2::hex, id, "EXP", lg2::hex,
          expected);

    co_return id == expected;
}

sdbusplus::async::task<bool> MP5998::unlockPasswordProtection()
{
    constexpr uint8_t passwordUnlockBit = 0x08;
    constexpr uint16_t passwordData = 0x0000;

    std::vector<uint8_t> tbuf;
    std::vector<uint8_t> rbuf;

    tbuf = buildByteVector(PMBusCmd::page, MPSPage::page0);
    if (!i2cInterface.sendReceive(tbuf, rbuf))
    {
        error("Failed to set page 0 for password unlock");
        co_return false;
    }

    tbuf = buildByteVector(MP5998Cmd::passwordReg, passwordData);
    if (!i2cInterface.sendReceive(tbuf, rbuf))
    {
        error("Failed to write password");
        co_return false;
    }

    tbuf = buildByteVector(PMBusCmd::statusCML);
    rbuf.resize(statusByteLength);
    if (!i2cInterface.sendReceive(tbuf, rbuf))
    {
        error("Failed to read STATUS_CML");
        co_return false;
    }

    bool unlocked = (rbuf[0] & passwordUnlockBit) == 0;

    co_return unlocked;
}

sdbusplus::async::task<bool> MP5998::unlockWriteProtection()
{
    std::vector<uint8_t> tbuf;
    std::vector<uint8_t> rbuf;

    tbuf = buildByteVector(PMBusCmd::page, MPSPage::page0);
    if (!i2cInterface.sendReceive(tbuf, rbuf))
    {
        error("Failed to set page 0 for write protection unlock");
        co_return false;
    }

    tbuf = buildByteVector(PMBusCmd::writeProtect, unlockData);
    if (!i2cInterface.sendReceive(tbuf, rbuf))
    {
        error("Failed to unlock write protection");
        co_return false;
    }

    debug("Write protection unlocked");
    co_return true;
}

sdbusplus::async::task<bool> MP5998::programAllRegisters()
{
    uint8_t currentPage = 0xFF;

    for (const auto& regData : configuration->registersData)
    {
        if (regData.page != currentPage)
        {
            std::vector<uint8_t> tbuf =
                buildByteVector(PMBusCmd::page, regData.page);
            std::vector<uint8_t> rbuf;
            if (!i2cInterface.sendReceive(tbuf, rbuf))
            {
                error("Failed to set page {PAGE}", "PAGE", regData.page);
                co_return false;
            }
            currentPage = regData.page;
        }

        std::vector<uint8_t> tbuf;
        std::vector<uint8_t> rbuf;

        tbuf.push_back(regData.addr);

        for (uint8_t i = 0; i < regData.length && i < 4; ++i)
        {
            tbuf.push_back(regData.data[i]);
        }

        if (!i2cInterface.sendReceive(tbuf, rbuf))
        {
            error("Failed to write register 0x{REG} on page {PAGE}", "REG",
                  lg2::hex, regData.addr, "PAGE", regData.page);
            co_return false;
        }
    }

    debug("All registers programmed successfully");
    co_return true;
}

sdbusplus::async::task<bool> MP5998::storeMTP()
{
    std::vector<uint8_t> tbuf;
    std::vector<uint8_t> rbuf;

    tbuf = buildByteVector(PMBusCmd::page, MPSPage::page0);
    if (!i2cInterface.sendReceive(tbuf, rbuf))
    {
        error("Failed to set page 0 for MTP store");
        co_return false;
    }

    tbuf = buildByteVector(PMBusCmd::storeUserCode);
    if (!i2cInterface.sendReceive(tbuf, rbuf))
    {
        error("Failed to send STORE_USER_ALL command");
        co_return false;
    }

    co_return true;
}

sdbusplus::async::task<bool> MP5998::waitForMTPComplete()
{
    constexpr uint16_t mtpStoreWaitmS = 1200;
    co_await sdbusplus::async::sleep_for(
        ctx, std::chrono::milliseconds(mtpStoreWaitmS));
    std::vector<uint8_t> tbuf = buildByteVector(PMBusCmd::statusCML);
    std::vector<uint8_t> rbuf;
    rbuf.resize(statusByteLength);

    if (!i2cInterface.sendReceive(tbuf, rbuf))
    {
        error("Failed to read STATUS_CML after MTP store");
        co_return false;
    }

    bool eepromFault = rbuf[0] & eepromFaultBit;

    if (eepromFault)
    {
        error("EEPROM fault detected after MTP store");
        co_return false;
    }

    co_return true;
}

sdbusplus::async::task<bool> MP5998::verifyCRC()
{
    uint32_t deviceCRC{0};
    // NOLINTBEGIN(clang-analyzer-core.uninitialized.Branch)
    bool getCRCSuccess = co_await getCRC(&deviceCRC);
    // NOLINTEND(clang-analyzer-core.uninitialized.Branch)
    if (!getCRCSuccess)
    {
        error("Failed to read CRC from device");
        co_return false;
    }

    bool crcMatch = (deviceCRC == configuration->crcUser);

    co_return crcMatch;
}

sdbusplus::async::task<bool> MP5998::getCRC(uint32_t* checksum)
{
    constexpr size_t crcLength = 2;

    std::vector<uint8_t> tbuf;
    std::vector<uint8_t> rbuf;

    tbuf = buildByteVector(PMBusCmd::page, MPSPage::page0);
    if (!i2cInterface.sendReceive(tbuf, rbuf))
    {
        error("Failed to set page 0 for CRC read");
        co_return false;
    }

    tbuf = buildByteVector(MP5998Cmd::crcUser);
    rbuf.resize(crcLength);
    if (!i2cInterface.sendReceive(tbuf, rbuf))
    {
        error("Failed to read CRC_USER register");
        co_return false;
    }

    *checksum = bytesToInt<uint32_t>(rbuf);

    co_return true;
}

sdbusplus::async::task<bool> MP5998::sendRestoreMTPCommand()
{
    std::vector<uint8_t> tbuf;
    std::vector<uint8_t> rbuf;

    tbuf = buildByteVector(PMBusCmd::page, MPSPage::page0);
    if (!i2cInterface.sendReceive(tbuf, rbuf))
    {
        error("Failed to set page 0 for MTP restore");
        co_return false;
    }

    tbuf = buildByteVector(PMBusCmd::restoreUserAll);
    if (!i2cInterface.sendReceive(tbuf, rbuf))
    {
        error("Failed to send RESTORE_ALL command");
        co_return false;
    }

    co_return true;
}

sdbusplus::async::task<bool> MP5998::checkEEPROMFaultAfterRestore()
{
    std::vector<uint8_t> tbuf;
    std::vector<uint8_t> rbuf;

    tbuf = buildByteVector(PMBusCmd::page, MPSPage::page0);
    if (!i2cInterface.sendReceive(tbuf, rbuf))
    {
        error("Failed to set page 0 for EEPROM fault check");
        co_return false;
    }

    tbuf = buildByteVector(PMBusCmd::statusCML);
    rbuf.resize(1);
    if (!i2cInterface.sendReceive(tbuf, rbuf))
    {
        error("Failed to read STATUS_CML register");
        co_return false;
    }

    bool eepromFault = (rbuf[0] & eepromFaultBit) != 0;

    co_return !eepromFault;
}

sdbusplus::async::task<bool> MP5998::restoreMTPAndVerify()
{
    constexpr uint16_t mtpRestoreWait = 1600;

    if (!co_await sendRestoreMTPCommand())
    {
        error("Failed to send RESTORE_ALL command");
        co_return false;
    }

    co_await sdbusplus::async::sleep_for(
        ctx, std::chrono::microseconds(mtpRestoreWait));
    if (!co_await checkEEPROMFaultAfterRestore())
    {
        error("EEPROM fault detected after MTP restore");
        co_return false;
    }

    co_return true;
}

bool MP5998::forcedUpdateAllowed()
{
    return true;
}

sdbusplus::async::task<bool> MP5998::updateFirmware(bool force)
{
    (void)force;

    if (!co_await checkId(PMBusCmd::mfrId, configuration->vendorId))
    {
        co_return false;
    }

    if (!co_await checkId(PMBusCmd::mfrModel, configuration->productId))
    {
        co_return false;
    }

    if (!co_await unlockWriteProtection())
    {
        co_return false;
    }

    if (!co_await programAllRegisters())
    {
        co_return false;
    }

    if (!co_await storeMTP())
    {
        co_return false;
    }

    if (!co_await waitForMTPComplete())
    {
        co_return false;
    }

    if (!co_await verifyCRC())
    {
        co_return false;
    }

    if (!co_await restoreMTPAndVerify())
    {
        co_return false;
    }

    co_return true;
}

} // namespace phosphor::software::VR
