/**
 * Copyright © 2024 IBM 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 "config.h"

#include "aei_updater.hpp"

#include "pmbus.hpp"
#include "types.hpp"
#include "updater.hpp"
#include "utility.hpp"

#include <phosphor-logging/lg2.hpp>

#include <fstream>

namespace aeiUpdater
{
constexpr uint8_t MAX_RETRIES = 0x02;    // Constants for retry limits

constexpr int ISP_STATUS_DELAY = 1200;   // Delay for ISP status check (1.2s)
constexpr int MEM_WRITE_DELAY = 5000;    // Memory write delay (5s)
constexpr int MEM_STRETCH_DELAY = 10;    // Delay between writes (10ms)
constexpr int MEM_COMPLETE_DELAY = 2000; // Delay before completion (2s)
constexpr int REBOOT_DELAY = 8000;       // Delay for reboot (8s)

constexpr uint8_t I2C_SMBUS_BLOCK_MAX = 0x20; // Max Read bytes from PSU
constexpr uint8_t FW_READ_BLOCK_SIZE = 0x20;  // Read bytes from FW file
constexpr uint8_t BLOCK_WRITE_SIZE = 0x25;    // I2C block write size
constexpr uint8_t READ_SEQ_ST_CML_SIZE = 0x6; // Read sequence and status CML
                                              // size
constexpr uint8_t START_SEQUENCE_INDEX = 0x1; // Starting sequence index
constexpr uint8_t STATUS_CML_INDEX = 0x5;     // Status CML read index

// Register addresses for commands.
constexpr uint8_t KEY_REGISTER = 0xF6;        // Key register
constexpr uint8_t STATUS_REGISTER = 0xF7;     // Status register
constexpr uint8_t ISP_MEMORY_REGISTER = 0xF9; // ISP memory register

// Define AEI ISP status register commands
constexpr uint8_t CMD_CLEAR_STATUS = 0x0; // Clear the status register
constexpr uint8_t CMD_RESET_SEQ = 0x01;   // This command will reset ISP OS for
                                          // another attempt of a sequential
                                          // programming operation.
constexpr uint8_t CMD_BOOT_ISP = 0x02; // Boot the In-System Programming System.
constexpr uint8_t CMD_BOOT_PWR = 0x03; // Attempt to boot the Power Management
                                       // OS.

// Define AEI ISP response status bit
constexpr uint8_t B_CHKSUM_ERR = 0x0; // The checksum verification unsuccessful
constexpr uint8_t B_CHKSUM_SUCCESS = 0x1; // The checksum verification
                                          // successful.
constexpr uint8_t B_MEM_ERR = 0x2;        // Memory boundry error indication.
constexpr uint8_t B_ALIGN_ERR = 0x4;      // Address error indication.
constexpr uint8_t B_KEY_ERR = 0x8;        // Invalid Key
constexpr uint8_t B_START_ERR = 0x10;     // Error indicator set at startup.
constexpr uint8_t B_IMG_MISSMATCH_ERR = 0x20; // Firmware image does not match
                                              // PSU
constexpr uint8_t B_ISP_MODE = 0x40;          // ISP mode
constexpr uint8_t B_ISP_MODE_CHKSUM_GOOD = 0x41; // ISP mode  & good checksum.
constexpr uint8_t B_PRGM_BUSY = 0x80;            // Write operation in progress.
constexpr uint8_t SUCCESSFUL_ISP_REBOOT_STATUS = 0x0; // Successful ISP reboot
                                                      // status

using namespace phosphor::logging;
namespace util = phosphor::power::util;

int AeiUpdater::doUpdate()
{
    i2cInterface = Updater::getI2C();
    if (i2cInterface == nullptr)
    {
        throw std::runtime_error("I2C interface error");
    }
    bool cleanFailedIspMode = false; // Flag to prevent download and continue to
                                     // restore the PSU to it's original state.

    // Set ISP mode by writing necessary keys and resetting ISP status
    if (!writeIspKey() || !writeIspMode() || !writeIspStatusReset())
    {
        lg2::error("Failed to set ISP key or mode or reset ISP status");
        cleanFailedIspMode = true;
    }

    if (cleanFailedIspMode)
    {
        return 1;
    }
    return 0; // Update successful.
}

bool AeiUpdater::writeIspKey()
{
    // ISP Key to unlock programming mode ( ASCII for "artY").
    constexpr std::array<uint8_t, 4> unlockData = {0x61, 0x72, 0x74,
                                                   0x59}; // ISP Key "artY"
    try
    {
        // Send ISP Key to unlock device for firmware update
        i2cInterface->write(KEY_REGISTER, unlockData.size(), unlockData.data());
        return true;
    }
    catch (const std::exception& e)
    {
        // Log failure if I2C write fails.
        lg2::error("I2C write failed: {ERROR}", "ERROR", e);
        return false;
    }
}

bool AeiUpdater::writeIspMode()
{
    // Attempt to set device in ISP mode with retries.
    uint8_t ispStatus = 0x0;
    for (int retry = 0; retry < MAX_RETRIES; ++retry)
    {
        try
        {
            // Write command to enter ISP mode.
            i2cInterface->write(STATUS_REGISTER, CMD_BOOT_ISP);
            // Delay to allow status register update.
            updater::internal::delay(ISP_STATUS_DELAY);
            // Read back status register to confirm ISP mode is active.
            i2cInterface->read(STATUS_REGISTER, ispStatus);

            if (ispStatus & B_ISP_MODE)
            {
                return true;
            }
        }
        catch (const std::exception& e)
        {
            // Log I2C error with each retry attempt.
            lg2::error("I2C error during ISP mode write/read: {ERROR}", "ERROR",
                       e);
        }
    }
    lg2::error("Failed to set ISP Mode");
    return false; // Failed to set ISP Mode after retries
}

bool AeiUpdater::writeIspStatusReset()
{
    // Reset ISP status register before firmware download.
    uint8_t ispStatus = 0;
    try
    {
        i2cInterface->write(STATUS_REGISTER,
                            CMD_RESET_SEQ); // Start reset sequence.
        for (int retry = 0; retry < MAX_RETRIES; ++retry)
        {
            i2cInterface->read(STATUS_REGISTER, ispStatus);
            if (ispStatus == B_ISP_MODE)
            {
                return true; // ISP status reset successfully.
            }
            i2cInterface->write(STATUS_REGISTER,
                                CMD_CLEAR_STATUS); // Clear status if
                                                   // not reset.
        }
    }
    catch (const std::exception& e)
    {
        // Log any errors encountered during reset sequence.
        lg2::error("I2C Read/Write error during ISP reset: {ERROR}", "ERROR",
                   e);
    }
    lg2::error("Failed to reset ISP Status");
    return false;
}

std::string AeiUpdater::getFirmwarePath()
{
    const std::string fspath =
        updater::internal::getFWFilenamePath(getImageDir());
    if (fspath.empty())
    {
        lg2::error("Firmware file path not found");
    }
    return fspath;
}

bool AeiUpdater::isFirmwareFileValid(const std::string& fspath)
{
    if (!updater::internal::validateFWFile(fspath))
    {
        lg2::error("Firmware validation failed");
        return false;
    }
    return true;
}

std::unique_ptr<std::ifstream>
    AeiUpdater::openFirmwareFile(const std::string& fspath)
{
    auto inputFile = updater::internal::openFirmwareFile(fspath);
    if (!inputFile)
    {
        lg2::error("Failed to open firmware file");
    }
    return inputFile;
}

std::vector<uint8_t> AeiUpdater::readFirmwareBlock(std::ifstream& file,
                                                   const size_t& bytesToRead)
{
    auto block = updater::internal::readFirmwareBytes(file, bytesToRead);
    return block;
}

std::vector<uint8_t>
    AeiUpdater::prepareCommandBlock(const std::vector<uint8_t>& dataBlockRead)
{
    std::vector<uint8_t> cmdBlockWrite = {ISP_MEMORY_REGISTER,
                                          BLOCK_WRITE_SIZE};

    cmdBlockWrite.insert(cmdBlockWrite.end(), byteSwappedIndex.begin(),
                         byteSwappedIndex.end());
    cmdBlockWrite.insert(cmdBlockWrite.end(), dataBlockRead.begin(),
                         dataBlockRead.end());

    // Resize to ensure it matches BLOCK_WRITE_SIZE + 1 and append CRC
    if (cmdBlockWrite.size() != BLOCK_WRITE_SIZE + 1)
    {
        cmdBlockWrite.resize(BLOCK_WRITE_SIZE + 1, 0xFF);
    }
    cmdBlockWrite.push_back(updater::internal::calculateCRC8(cmdBlockWrite));
    // Remove the F9 and byte count
    cmdBlockWrite.erase(cmdBlockWrite.begin(), cmdBlockWrite.begin() + 2);

    return cmdBlockWrite;
}

void AeiUpdater::ispReboot()
{
    updater::internal::delay(
        MEM_COMPLETE_DELAY); // Delay before starting the reboot process

    try
    {
        // Write reboot command to the status register
        i2cInterface->write(STATUS_REGISTER, CMD_BOOT_PWR);

        updater::internal::delay(
            REBOOT_DELAY); // Add delay after writing reboot command
    }
    catch (const std::exception& e)
    {
        lg2::error("I2C write error during reboot: {ERROR}", "ERROR", e);
    }
}

bool AeiUpdater::ispReadRebootStatus()
{
    try
    {
        // Read from the status register to verify reboot
        uint8_t data = 1; // Initialize data to a non-zero value
        i2cInterface->read(STATUS_REGISTER, data);

        uint8_t status = SUCCESSFUL_ISP_REBOOT_STATUS;
        // If the reboot was successful, the read data should be 0
        if (data == status)
        {
            lg2::info("ISP Status Reboot successful.");
            return true;
        }
    }
    catch (const std::exception& e)
    {
        lg2::error("I2C read error during reboot attempt: {ERROR}", "ERROR", e);
    }
    return false;
}

} // namespace aeiUpdater
