#include "lattice.hpp"

#include <phosphor-logging/lg2.hpp>

#include <algorithm>
#include <fstream>
#include <map>
#include <thread>
#include <vector>

using sdbusplus::async::details::context_friend;

constexpr uint8_t busyWaitmaxRetry = 30;
constexpr uint8_t busyFlagBit = 0x80;
constexpr std::chrono::milliseconds waitBusyTime(200);

static constexpr std::string_view tagQF = "QF";
static constexpr std::string_view tagUH = "UH";
static constexpr std::string_view tagCFStart = "L000";
static constexpr std::string_view tagChecksum = "C";
static constexpr std::string_view tagUserCode = "NOTE User Electronic";
static constexpr std::string_view tagEbrInitData = "NOTE EBR_INIT DATA";

constexpr uint8_t isOK = 0;
constexpr uint8_t isReady = 0;
constexpr uint8_t busyOrReadyBit = 4;
constexpr uint8_t failOrOKBit = 5;

constexpr bool enableUpdateEbrInit = false;

enum cpldI2cCmd
{
    commandEraseFlash = 0x0E,
    commandDisableConfigInterface = 0x26,
    commandReadStatusReg = 0x3C,
    commandResetConfigFlash = 0x46,
    commandProgramDone = 0x5E,
    commandProgramPage = 0x70,
    commandEnableConfigMode = 0x74,
    commandReadFwVersion = 0xC0,
    commandProgramUserCode = 0xC2,
    commandReadDeviceId = 0xE0,
    commandReadBusyFlag = 0xF0,
};

static uint8_t reverse_bit(uint8_t b)
{
    b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
    b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
    b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
    return b;
}

const std::map<std::string, std::vector<uint8_t>> xo2xo3DeviceIdMap = {
    {"LCMXO3LF-4300C", {0x61, 0x2b, 0xc0, 0x43}},
    {"LCMXO3LF-4300", {0x61, 0x2b, 0xc0, 0x43}},
    {"LCMXO3LF-6900", {0x61, 0x2b, 0xd0, 0x43}},
    {"LCMXO3D-4300", {0x01, 0x2e, 0x20, 0x43}},
    {"LCMXO3D-9400", {0x21, 0x2e, 0x30, 0x43}},
};

static int findNumberSize(const std::string& end, const std::string& start,
                          const std::string& line)
{
    auto pos1 = line.find(start);
    auto pos2 = line.find(end);

    if (pos1 == std::string::npos || pos2 == std::string::npos || pos1 >= pos2)
    {
        return false;
    }

    return static_cast<int>(pos2 - pos1 - 1);
}

bool CpldLatticeManager::jedFileParser()
{
    bool cfStart = false;
    bool ufmStart = false; // for isLCMXO3D
    bool ufmPrepare = false;
    bool versionStart = false;
    bool checksumStart = false;
    bool ebrInitDataStart = false;
    int numberSize = 0;

    if (image == nullptr || imageSize == 0)
    {
        lg2::error(
            "Error: JED file is empty or not found. Please check the file.");
        return false;
    }

    // Convert binary data to a string
    std::string content(reinterpret_cast<const char*>(image), imageSize);
    // Use stringstream to simulate file reading
    std::istringstream iss(content);
    std::string line;

    // Parsing JED file
    while (getline(iss, line))
    {
        if (line.rfind(tagQF, 0) == 0)
        {
            numberSize = findNumberSize("*", "F", line);
            if (numberSize <= 0)
            {
                lg2::error("Error in parsing QF tag");
                return false;
            }
            static constexpr auto start = tagQF.length();
            fwInfo.QF = std::stoul(line.substr(start, numberSize));

            lg2::debug("QF Size = {QF}", "QF", fwInfo.QF);
        }
        else if (line.rfind(tagCFStart, 0) == 0)
        {
            cfStart = true;
        }
        else if (enableUpdateEbrInit && line.rfind(tagEbrInitData, 0) == 0)
        {
            ebrInitDataStart = true;
        }
        else if (ufmPrepare)
        {
            ufmPrepare = false;
            ufmStart = true;
            continue;
        }
        else if (line.rfind(tagUserCode, 0) == 0)
        {
            versionStart = true;
        }
        else if (line.rfind(tagChecksum, 0) == 0)
        {
            checksumStart = true;
        }

        if (line.rfind("NOTE DEVICE NAME:", 0) == 0)
        {
            lg2::error(line.c_str());
            if (line.find(chip) != std::string::npos)
            {
                lg2::debug("[OK] The image device name match with chip name");
            }
            else
            {
                lg2::debug("STOP UPDATEING: The image not match with chip.");
                return false;
            }
        }

        if (cfStart)
        {
            // L000
            if ((line.rfind(tagCFStart, 0)) && (line.size() != 1))
            {
                if ((line.rfind('0', 0) == 0) || (line.rfind('1', 0) == 0))
                {
                    while (!line.empty())
                    {
                        auto binaryStr = line.substr(0, 8);
                        try
                        {
                            fwInfo.cfgData.push_back(
                                std::stoi(binaryStr, 0, 2));
                            line.erase(0, 8);
                        }
                        catch (const std::invalid_argument& error)
                        {
                            break;
                        }
                        catch (...)
                        {
                            lg2::error("Error while parsing CF section");
                            return false;
                        }
                    }
                }
                else
                {
                    lg2::debug("CF size = {CF}", "CF", fwInfo.cfgData.size());
                    cfStart = false;
                    if (!ebrInitDataStart)
                    {
                        ufmPrepare = true;
                    }
                }
            }
        }
        else if (enableUpdateEbrInit && ebrInitDataStart)
        {
            // NOTE EBR_INIT DATA
            if ((line.rfind(tagEbrInitData, 0)) && (line.size() != 1))
            {
                if ((line.rfind('L', 0)) && (line.size() != 1))
                {
                    if ((line.rfind('0', 0) == 0) || (line.rfind('1', 0) == 0))
                    {
                        while (!line.empty())
                        {
                            auto binaryStr = line.substr(0, 8);
                            try
                            {
                                fwInfo.cfgData.push_back(
                                    std::stoi(binaryStr, 0, 2));
                                line.erase(0, 8);
                            }
                            catch (const std::invalid_argument& error)
                            {
                                break;
                            }
                            catch (...)
                            {
                                lg2::error("Error while parsing CF section");
                                return false;
                            }
                        }
                    }
                    else
                    {
                        lg2::debug("CF size with EBR_INIT Data = {CF}", "CF",
                                   fwInfo.cfgData.size());
                        ebrInitDataStart = false;
                        ufmPrepare = true;
                    }
                }
            }
        }
        else if ((checksumStart) && (line.size() != 1))
        {
            checksumStart = false;
            numberSize = findNumberSize("*", "C", line);
            if (numberSize <= 0)
            {
                lg2::error("Error in parsing checksum");
                return false;
            }
            static constexpr auto start = tagChecksum.length();
            std::istringstream iss(line.substr(start, numberSize));
            iss >> std::hex >> fwInfo.checksum;

            lg2::debug("Checksum = {CHECKSUM}", "CHECKSUM", fwInfo.checksum);
        }
        else if (versionStart)
        {
            if ((line.rfind(tagUserCode, 0)) && (line.size() != 1))
            {
                versionStart = false;

                if (line.rfind(tagUH, 0) == 0)
                {
                    numberSize = findNumberSize("*", "H", line);
                    if (numberSize <= 0)
                    {
                        lg2::error("Error in parsing version");
                        return false;
                    }
                    static constexpr auto start = tagUH.length();
                    std::istringstream iss(line.substr(start, numberSize));
                    iss >> std::hex >> fwInfo.version;

                    lg2::debug("UserCode = {USERCODE}", "USERCODE",
                               fwInfo.version);
                }
            }
        }
        else if (ufmStart)
        {
            if ((line.rfind('L', 0)) && (line.size() != 1))
            {
                if ((line.rfind('0', 0) == 0) || (line.rfind('1', 0) == 0))
                {
                    while (!line.empty())
                    {
                        auto binaryStr = line.substr(0, 8);
                        try
                        {
                            fwInfo.ufmData.push_back(
                                std::stoi(binaryStr, 0, 2));
                            line.erase(0, 8);
                        }
                        catch (const std::invalid_argument& error)
                        {
                            break;
                        }
                        catch (...)
                        {
                            lg2::error("Error while parsing UFM section");
                            return false;
                        }
                    }
                }
                else
                {
                    lg2::debug("UFM size = {UFM}", "UFM",
                               fwInfo.ufmData.size());
                    ufmStart = false;
                }
            }
        }
    }

    return true;
}

bool CpldLatticeManager::verifyChecksum()
{
    // Compute check sum
    unsigned int jedFileCheckSum = 0;
    for (unsigned i = 0; i < fwInfo.cfgData.size(); i++)
    {
        jedFileCheckSum += reverse_bit(fwInfo.cfgData.at(i));
    }
    for (unsigned i = 0; i < fwInfo.ufmData.size(); i++)
    {
        jedFileCheckSum += reverse_bit(fwInfo.ufmData.at(i));
    }
    lg2::debug("jedFileCheckSum = {JEDFILECHECKSUM}", "JEDFILECHECKSUM",
               jedFileCheckSum);
    jedFileCheckSum = jedFileCheckSum & 0xffff;

    if ((fwInfo.checksum != jedFileCheckSum) || (fwInfo.checksum == 0))
    {
        lg2::error("CPLD JED File CheckSum Error = {JEDFILECHECKSUM}",
                   "JEDFILECHECKSUM", jedFileCheckSum);
        return false;
    }

    lg2::debug("JED File Checksum compare success");
    return true;
}

sdbusplus::async::task<bool> CpldLatticeManager::readDeviceId()
{
    auto sched = context_friend::get_scheduler(ctx);
    std::vector<uint8_t> command = {commandReadDeviceId, 0x0, 0x0, 0x0};
    constexpr size_t resSize = 4;
    std::vector<uint8_t> readData(resSize, 0);
    bool success = co_await stdexec::starts_on(
        sched, i2cInterface.sendReceive(command.data(), command.size(),
                                        readData.data(), resSize));
    if (!success)
    {
        lg2::error(
            "Fail to read device Id. Please check the I2C bus and address.");
        co_return false;
    }

    auto chipWantToUpdate = xo2xo3DeviceIdMap.find(chip);

    if (chipWantToUpdate != xo2xo3DeviceIdMap.end() &&
        chipWantToUpdate->second == readData)
    {
        if (chip.rfind("LCMXO3D", 0) == 0)
        {
            isLCMXO3D = true;
            if (!target.empty() && target != "CFG0" && target != "CFG1")
            {
                lg2::error("Unknown target. Only CFG0 and CFG1 are supported.");
                co_return false;
            }
        }

        lg2::debug("Device ID match with chip. Chip name: {CHIPNAME}",
                   "CHIPNAME", chip);
        co_return true;
    }

    lg2::error(
        "The device id not match with chip. Only the following chip names are supported: ");
    for (const auto& chip : xo2xo3DeviceIdMap)
    {
        lg2::error(chip.first.c_str());
    }
    co_return false;
}

sdbusplus::async::task<bool> CpldLatticeManager::enableProgramMode()
{
    auto sched = context_friend::get_scheduler(ctx);
    std::vector<uint8_t> command = {commandEnableConfigMode, 0x08, 0x0, 0x0};
    bool success = co_await stdexec::starts_on(
        sched,
        i2cInterface.sendReceive(command.data(), command.size(), nullptr, 0));

    if (!success)
    {
        co_return false;
    }

    if (!(co_await waitBusyAndVerify()))
    {
        lg2::error("Wait busy and verify fail");
        co_return false;
    }
    co_await sdbusplus::async::sleep_for(ctx, waitBusyTime);
    co_return true;
}

sdbusplus::async::task<bool> CpldLatticeManager::eraseFlash()
{
    auto sched = context_friend::get_scheduler(ctx);
    std::vector<uint8_t> command;

    if (isLCMXO3D)
    {
        /*
        Erase the different internal
        memories. The bit in YYY defines
        which memory is erased in Flash
        access mode.
        Bit 1=Enable
        8 Erase CFG0
        9 Erase CFG1
        10 Erase UFM0
        11 Erase UFM1
        12 Erase UFM2
        13 Erase UFM3
        14 Erase CSEC
        15 Erase USEC
        16 Erase PUBKEY
        17 Erase AESKEY
        18 Erase FEA
        19 Reserved
        commandEraseFlash = 0x0E, 0Y YY 00
        */
        if (target.empty() || target == "CFG0")
        {
            command = {commandEraseFlash, 0x00, 0x01, 0x00};
        }
        else if (target == "CFG1")
        {
            command = {commandEraseFlash, 0x00, 0x02, 0x00};
        }
        else
        {
            lg2::error("Error: unknown target.");
            co_return false;
        }
    }
    else
    {
        command = {commandEraseFlash, 0xC, 0x0, 0x0};
    }

    bool success = co_await stdexec::starts_on(
        sched,
        i2cInterface.sendReceive(command.data(), command.size(), nullptr, 0));
    if (!success)
    {
        co_return false;
    }

    if (!(co_await waitBusyAndVerify()))
    {
        lg2::error("Wait busy and verify fail");
        co_return false;
    }
    co_await sdbusplus::async::sleep_for(ctx, waitBusyTime);
    co_return true;
}

sdbusplus::async::task<bool> CpldLatticeManager::resetConfigFlash()
{
    auto sched = context_friend::get_scheduler(ctx);
    std::vector<uint8_t> command;
    if (isLCMXO3D)
    {
        /*
        Set Page Address pointer to the
        beginning of the different internal
        Flash sectors. The bit in YYYY
        defines which sector is selected.
        Bit Flash sector selected
        8 CFG0
        9 CFG1
        10 FEA
        11 PUBKEY
        12 AESKEY
        13 CSEC
        14 UFM0
        15 UFM1
        16 UFM2
        17 UFM3
        18 USEC
        19 Reserved
        20 Reserved
        21 Reserved
        22 Reserved
        commandResetConfigFlash = 0x46, YY YY 00
        */
        if (target.empty() || target == "CFG0")
        {
            command = {commandResetConfigFlash, 0x00, 0x01, 0x00};
        }
        else if (target == "CFG1")
        {
            command = {commandResetConfigFlash, 0x00, 0x02, 0x00};
        }
        else
        {
            lg2::error(
                "Error: unknown target. Only CFG0 and CFG1 are supported.");
            co_return false;
        }
    }
    else
    {
        command = {commandResetConfigFlash, 0x0, 0x0, 0x0};
    }

    co_return co_await stdexec::starts_on(
        sched,
        i2cInterface.sendReceive(command.data(), command.size(), nullptr, 0));
}

sdbusplus::async::task<bool> CpldLatticeManager::writeProgramPage()
{
    /*
    Program one NVCM/Flash page. Can be
    used to program the NVCM0/CFG or
    NVCM1/UFM.
    */
    auto sched = context_friend::get_scheduler(ctx);
    std::vector<uint8_t> command = {commandProgramPage, 0x0, 0x0, 0x01};
    size_t iterSize = 16;

    for (size_t i = 0; i < fwInfo.cfgData.size(); i += iterSize)
    {
        double progressRate =
            ((double(i) / double(fwInfo.cfgData.size())) * 100);
        std::cout << "Update :" << std::fixed << std::dec
                  << std::setprecision(2) << progressRate << "% \r";

        uint8_t len = ((i + iterSize) < fwInfo.cfgData.size())
                          ? iterSize
                          : (fwInfo.cfgData.size() - i);
        std::vector<uint8_t> data = command;

        data.insert(
            data.end(), fwInfo.cfgData.begin() + static_cast<std::ptrdiff_t>(i),
            fwInfo.cfgData.begin() + static_cast<std::ptrdiff_t>(i + len));

        bool success = co_await stdexec::starts_on(
            sched,
            i2cInterface.sendReceive(data.data(), data.size(), nullptr, 0));
        if (!success)
        {
            co_return false;
        }

        /*
         Reference spec
         Important! If don't sleep, it will take a long time to update.
        */
        co_await sdbusplus::async::sleep_for(ctx,
                                             std::chrono::microseconds(200));

        if (!(co_await waitBusyAndVerify()))
        {
            lg2::error("Wait busy and verify fail");
            co_return false;
        }

        data.clear();
    }

    co_return true;
}

sdbusplus::async::task<bool> CpldLatticeManager::programUserCode()
{
    auto sched = context_friend::get_scheduler(ctx);
    std::vector<uint8_t> command = {commandProgramUserCode, 0x0, 0x0, 0x0};
    for (int i = 3; i >= 0; i--)
    {
        command.push_back((fwInfo.version >> (i * 8)) & 0xFF);
    }
    bool success = co_await stdexec::starts_on(
        sched,
        i2cInterface.sendReceive(command.data(), command.size(), nullptr, 0));

    if (!success)
    {
        co_return false;
    }

    if (!(co_await waitBusyAndVerify()))
    {
        lg2::error("Wait busy and verify fail");
        co_return false;
    }

    co_return true;
}

sdbusplus::async::task<bool> CpldLatticeManager::programDone()
{
    auto sched = context_friend::get_scheduler(ctx);
    std::vector<uint8_t> command = {commandProgramDone, 0x0, 0x0, 0x0};
    bool success = co_await stdexec::starts_on(
        sched,
        i2cInterface.sendReceive(command.data(), command.size(), nullptr, 0));

    if (!success)
    {
        co_return false;
    }
    if (!(co_await waitBusyAndVerify()))
    {
        lg2::error("Wait busy and verify fail");
        co_return false;
    }

    co_return true;
}

sdbusplus::async::task<bool> CpldLatticeManager::disableConfigInterface()
{
    auto sched = context_friend::get_scheduler(ctx);
    std::vector<uint8_t> command = {commandDisableConfigInterface, 0x0, 0x0};

    bool success = co_await stdexec::starts_on(
        sched,
        i2cInterface.sendReceive(command.data(), command.size(), nullptr, 0));

    co_return success;
}

sdbusplus::async::task<bool> CpldLatticeManager::waitBusyAndVerify()
{
    uint8_t retry = 0;

    while (retry <= busyWaitmaxRetry)
    {
        uint8_t busyFlag = 0xff;

        if (!(co_await readBusyFlag(busyFlag)))
        {
            lg2::error("Fail to read busy flag.");
            co_return false;
        }

        if (busyFlag & busyFlagBit)
        {
            co_await sdbusplus::async::sleep_for(ctx, waitBusyTime);
            retry++;
            if (retry > busyWaitmaxRetry)
            {
                lg2::error(
                    "Status Reg : Busy! Please check the I2C bus and address.");
                co_return false;
            }
        }
        else
        {
            break;
        }
    } // while loop busy check

    // Check out status reg
    uint8_t statusReg = 0xff;

    if (!(co_await readStatusReg(statusReg)))
    {
        lg2::error("Fail to read status register.");
        co_return false;
    }

    if (((statusReg >> busyOrReadyBit) & 1) == isReady &&
        ((statusReg >> failOrOKBit) & 1) == isOK)
    {
        lg2::debug("Status Reg : OK");
        co_return true;
    }

    lg2::error("Status Reg : Fail! Please check the I2C bus and address.");
    co_return false;
}

sdbusplus::async::task<bool> CpldLatticeManager::readBusyFlag(uint8_t& busyFlag)
{
    auto sched = context_friend::get_scheduler(ctx);
    std::vector<uint8_t> command = {commandReadBusyFlag, 0x0, 0x0, 0x0};
    constexpr size_t resSize = 1;
    std::vector<uint8_t> readData(resSize, 0);
    bool success = co_await stdexec::starts_on(
        sched, i2cInterface.sendReceive(command.data(), command.size(),
                                        readData.data(), resSize));

    if (!success || (readData.size() != resSize))
    {
        co_return false;
    }
    busyFlag = readData.at(0);
    co_return true;
}

sdbusplus::async::task<bool> CpldLatticeManager::readStatusReg(
    uint8_t& statusReg)
{
    auto sched = context_friend::get_scheduler(ctx);
    std::vector<uint8_t> command = {commandReadStatusReg, 0x0, 0x0, 0x0};
    constexpr size_t resSize = 4;
    std::vector<uint8_t> readData(resSize, 0);
    bool success = co_await stdexec::starts_on(
        sched, i2cInterface.sendReceive(command.data(), command.size(),
                                        readData.data(), resSize));

    if (!success || (readData.size() != resSize))
    {
        co_return false;
    }
    /*
    Read Status Register
    [LSC_READ_STATUS]
    0x3C 00 00 00 N/A YY YY YY YY Bit 1 0
    12 Busy Ready
    13 Fail OK
        */
    statusReg = readData.at(2);
    co_return true;
}

sdbusplus::async::task<bool> CpldLatticeManager::readUserCode(
    uint32_t& userCode)
{
    auto sched = context_friend::get_scheduler(ctx);
    std::vector<uint8_t> command = {commandReadFwVersion, 0x0, 0x0, 0x0};
    constexpr size_t resSize = 4;
    std::vector<uint8_t> readData(resSize, 0);
    bool success = co_await stdexec::starts_on(
        sched, i2cInterface.sendReceive(command.data(), command.size(),
                                        readData.data(), resSize));

    if (!success)
    {
        co_return false;
    }

    for (size_t i = 0; i < resSize; i++)
    {
        userCode |= readData.at(i) << ((3 - i) * 8);
    }
    co_return true;
}

sdbusplus::async::task<bool> CpldLatticeManager::XO2XO3FamilyUpdate(
    std::function<bool(int)> progressCallBack)
{
    if (progressCallBack == nullptr)
    {
        lg2::error("Error: progressCallBack is null.");
        co_return false;
    }

    if (!(co_await readDeviceId()))
    {
        co_return false;
    }
    progressCallBack(10);

    if (!jedFileParser())
    {
        lg2::error("JED file parsing failed");
        co_return false;
    }
    progressCallBack(15);

    if (!verifyChecksum())
    {
        lg2::error("Checksum verification failed");
        co_return false;
    }
    progressCallBack(20);

    if (!isLCMXO3D)
    {
        lg2::error("is not LCMXO3D");
    }

    lg2::debug("Starts to update ...");
    lg2::debug("Enable program mode.");
    progressCallBack(25);

    co_await waitBusyAndVerify();

    if (!(co_await enableProgramMode()))
    {
        lg2::error("Enable program mode failed.");
        co_return false;
    }
    progressCallBack(30);

    lg2::debug("Erase flash.");
    if (!(co_await eraseFlash()))
    {
        lg2::error("Erase flash failed.");
        co_return false;
    }
    progressCallBack(40);

    lg2::debug("Reset config flash.");
    if (!(co_await resetConfigFlash()))
    {
        lg2::error("Reset config flash failed.");
        co_return false;
    }
    progressCallBack(50);

    lg2::debug("Write program page ...");
    if (!(co_await writeProgramPage()))
    {
        lg2::error("Write program page failed.");
        co_return false;
    }
    lg2::debug("Write program page done.");
    progressCallBack(60);

    lg2::debug("Program user code.");
    if (!(co_await programUserCode()))
    {
        lg2::error("Program user code failed.");
        co_return false;
    }
    progressCallBack(70);

    if (!(co_await programDone()))
    {
        lg2::error("Program not done.");
        co_return false;
    }
    progressCallBack(80);

    lg2::debug("Disable config interface.");
    if (!(co_await disableConfigInterface()))
    {
        lg2::error("Disable Config Interface failed.");
        co_return false;
    }
    progressCallBack(90);

    lg2::debug("Update completed!");

    co_return true;
}

sdbusplus::async::task<bool> CpldLatticeManager::updateFirmware(
    std::function<bool(int)> progressCallBack)
{
    if (xo2xo3DeviceIdMap.find(chip) != xo2xo3DeviceIdMap.end())
    {
        co_return co_await XO2XO3FamilyUpdate(progressCallBack);
    }
    lg2::error("Unsupported chip type: {CHIP}", "CHIP", chip);
    co_return false;
}

std::string uint32ToHexStr(uint32_t value)
{
    std::ostringstream oss;
    oss << std::setfill('0') << std::setw(8) << std::hex << std::uppercase
        << value;
    return oss.str();
}

sdbusplus::async::task<bool> CpldLatticeManager::getVersion(
    std::string& version)
{
    uint32_t userCode = 0;

    if (target.empty())
    {
        if (!(co_await readUserCode(userCode)))
        {
            lg2::error("Read usercode failed.");
            co_return false;
        }

        lg2::debug("CPLD version: {VERSION}", "VERSION", userCode);
    }
    else if (target == "CFG0" || target == "CFG1")
    {
        isLCMXO3D = true;
        co_await waitBusyAndVerify();

        if (!(co_await enableProgramMode()))
        {
            lg2::error("Enable program mode failed.");
            co_return false;
        }

        if (!(co_await resetConfigFlash()))
        {
            lg2::error("Reset config flash failed.");
            co_return false;
        }

        if (!(co_await readUserCode(userCode)))
        {
            lg2::error("Read usercode failed.");
            co_return false;
        }

        if (!(co_await programDone()))
        {
            lg2::error("Program not done.");
            co_return false;
        }

        if (!(co_await disableConfigInterface()))
        {
            lg2::error("Disable Config Interface failed.");
            co_return false;
        }

        lg2::debug("CPLD {TARGET} version: {VERSION}", "TARGET", target,
                   "VERSION", userCode);
    }
    else
    {
        lg2::error("Error: unknown target.");
        co_return false;
    }

    if (userCode == 0)
    {
        lg2::error("User code is zero, cannot get version.");
        co_return false;
    }
    version = uint32ToHexStr(userCode);
    co_return true;
}
