// Copyright 2024 Google LLC
//
// 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 "payload_update.hpp"

#include "google3/host_commands.h"

#include "message_util.hpp"
#include "sys.hpp"

#include <fcntl.h>
#include <unistd.h>

#include <boost/endian/conversion.hpp>
#include <stdplus/print.hpp>
#include <stdplus/raw.hpp>
#include <xyz/openbmc_project/Control/Hoth/error.hpp>

#include <array>
#include <cstdint>
#include <format>
#include <memory>
#include <span>
#include <string>
#include <vector>

namespace google
{
namespace hoth
{
namespace internal
{

enum hoth_status : uint16_t
{
    /*
      There is no update payload pending confirmation
    */
    HOTH_PAYLOAD_UPDATE_CONFIRM_NO_PENDING_PAYLOAD = 0xD004,
};

using sdbusplus::error::xyz::openbmc_project::control::hoth::ResponseFailure;

void PayloadUpdateImpl::initiate() const
{
    sendCommand(PAYLOAD_UPDATE_INITIATE);
}

void PayloadUpdateImpl::erase(const uint32_t offset, const uint32_t size) const
{
    sendCommand(PAYLOAD_UPDATE_ERASE, offset, size);
}

bool PayloadUpdateImpl::findDescriptor(const std::string& path,
                                       uint32_t* desc_offset) const
{

    Fd fd(sys->open(path.c_str(), O_RDONLY), sys);

    if (*fd < 0)
    {
        (void)fd.release();
        throw errnoException(std::format("Failed to open file {}", path));
    }

    auto seekRet = sys->lseek(*fd, 0, SEEK_END);
    size_t fsize = seekRet;

    if (seekRet < 0)
    {
        throw errnoException(std::format("Error seeking on file", path));
    }

    uint64_t read_data = 0;
    bool desc_found = false;

    // Find the nearest aligned address to the end of the file. We can't
    // assume that the file-size is aligned.
    ssize_t offset =
        static_cast<ssize_t>((fsize / kImageDescriptorAlignment) * kImageDescriptorAlignment);
    if (offset + sizeof(kDescriptorMagic) > fsize)
    {
        offset -= kImageDescriptorAlignment;
    }

    for (; offset >= 0; offset -= kImageDescriptorAlignment)
    {
        auto seek = sys->lseek(*fd, offset, SEEK_SET);
        if (seek < 0)
        {
            throw errnoException(std::format("Error seeking on file", path));
        }

        auto actualReadSize = sys->read(*fd, &read_data, sizeof(read_data));

        if (actualReadSize < 0)
        {
            throw errnoException(
                std::format("Failed to read from file {}", path));
        }

        if (read_data == kDescriptorMagic)
        {
            if (desc_offset)
            {
                *desc_offset = offset;
                desc_found = true;
                break;
            }
        }
    }

    return desc_found;
}

void PayloadUpdateImpl::eraseAndSendStaticWPRegions(const std::string& path,
                                                    uint32_t desc_offset) const
{

    Fd fd(sys->open(path.c_str(), O_RDONLY), sys);

    if (*fd < 0)
    {
        (void)fd.release();
        throw errnoException(std::format("Failed to open file {}", path));
    }

    struct image_descriptor descriptor;

    if (sys->lseek(*fd, desc_offset, SEEK_SET) < 0)
    {
        throw errnoException(std::format("Error seeking on file", path));
    }
    auto actualReadSize = sys->read(*fd, &descriptor, sizeof(descriptor));

    if (actualReadSize < 0)
    {
        throw errnoException(std::format("Failed to read from file {}", path));
    }

    if (descriptor.descriptor_magic != DESCRIPTOR_MAGIC ||
        descriptor.descriptor_offset != desc_offset ||
        descriptor.region_count == 0)
    {
        throw errnoException(
            std::format("Invalid descriptor at offset {}", path));
    }

    std::vector<struct image_region> image_regions(descriptor.region_count);

    actualReadSize =
        sys->read(*fd, image_regions.data(),
                  sizeof(struct image_region) * descriptor.region_count);
    if (actualReadSize < 0)
    {
        throw errnoException(std::format("Failed to read from file {}", path));
    }

    // Erase all the static and Write Protected regions of the payload
    for (uint32_t i = 0; i < descriptor.region_count; i++)
    {
        if ((image_regions[i].region_attributes & IMAGE_REGION_STATIC) ||
            (image_regions[i].region_attributes & IMAGE_REGION_WRITE_PROTECTED))
        {
            if (image_regions[i].region_size == 0 ||
                (image_regions[i].region_size % kSectorSizeBytes) != 0)
            {
                throw errnoException(std::format("invalid staging area size"));
            }
            uint32_t regionOffset = image_regions[i].region_offset;
            uint32_t toEraseSize = image_regions[i].region_size;
            while (toEraseSize >= kEraseChunkSizeBytes)
            {
                sendCommand(PAYLOAD_UPDATE_ERASE, regionOffset,
                            kEraseChunkSizeBytes);
                regionOffset += kEraseChunkSizeBytes;
                toEraseSize -= kEraseChunkSizeBytes;
            }
            if (toEraseSize > 0)
            {
                sendCommand(PAYLOAD_UPDATE_ERASE, regionOffset, toEraseSize);
            }
        }
    }

    // Read and send static and WP sections of the payload
    for (uint32_t i = 0; i < descriptor.region_count; i++)
    {
        if ((image_regions[i].region_attributes & IMAGE_REGION_STATIC) ||
            (image_regions[i].region_attributes & IMAGE_REGION_WRITE_PROTECTED))
        {
            uint32_t offset = image_regions[i].region_offset;
            auto regionSize = image_regions[i].region_size;
            size_t readSize = 0;
            std::vector<uint8_t> readBuffer(max_packet_size);

            if (sys->lseek(*fd, offset, SEEK_SET) != offset)
            {
                throw errnoException(
                    std::format("Failed to read file size {}", path));
            }
            do
            {
                if (regionSize <= max_packet_size)
                {
                    readSize = regionSize;
                } else
                {
                    readSize = max_packet_size;
                }

                if (!sys->read(*fd, readBuffer.data(), readSize))
                {
                    throw errnoException(
                        std::format("Failed to read from file {}", path));
                }

                // Decided not to use initializer list to create the span here
                // as actualReadSize is ssize_t and we'd need to static_cast
                trimAndSend(std::span<uint8_t>(readBuffer.data(), readSize),
                            offset);
                offset += readSize;
                regionSize -= readSize;

            } while (regionSize); // actualReadSize will be 0 when EOF is
                                  // reached, exit loop
        }
    }
}

void PayloadUpdateImpl::eraseAndSendStaticWP(const std::string& path) const
{

    uint32_t desc_offset = 0;

    if (!findDescriptor(path, &desc_offset))
    {
        throw errnoException(std::format("No valid descriptor found"));
    }

    eraseAndSendStaticWPRegions(path, desc_offset);
}

void PayloadUpdateImpl::read(uint32_t offset, std::span<uint8_t> data) const
{
    std::vector<uint8_t> buf;
    auto rsp = sendCommand(buf, PAYLOAD_UPDATE_READ, offset, data.size());
    if (rsp.size() != data.size())
    {
        stdplus::print(
            stderr,
            "Payload command received a short response from Hoth `{} < {}`\n",
            rsp.size(), data.size());
        throw ResponseFailure();
    }
    memcpy(data.data(), rsp.data(), data.size());
}

void PayloadUpdateImpl::verify() const
{
    payload_update_packet request = {};
    request.type = PAYLOAD_UPDATE_VERIFY_DESCRIPTOR;
    auto buf = hostCmd->sendCommand(EC_CMD_BOARD_SPECIFIC_BASE +
                                        EC_PRV_CMD_HOTH_PAYLOAD_UPDATE,
                                    0, &request, sizeof(request));
    std::span<uint8_t> rsp = buf;
    auto& hdr = stdplus::raw::extractRef<RspHeader>(rsp);

    // In case PAYLOAD_UPDATE_VERIFY is not supported (EC_RES_ERROR),
    // we fall back to PAYLOAD_UPDATE_VERIFY instead.
    if (hdr.result == EC_RES_INVALID_PARAM || hdr.result == EC_RES_ERROR)
    {
        sendCommand(PAYLOAD_UPDATE_VERIFY);
        return;
    }
    if (hdr.result != EC_RES_SUCCESS)
    {
        stdplus::print(stderr, "VERIFY_DESCRIPTOR error: {:#x}\n",
                       static_cast<uint8_t>(hdr.result));
        throw ResponseFailure();
    }
}

payload_update_status PayloadUpdateImpl::getStatus() const
{
    std::vector<uint8_t> buf;
    std::span<const uint8_t> output =
        sendCommand(buf, PAYLOAD_UPDATE_GET_STATUS);

    return stdplus::raw::copyFrom<payload_update_status>(output);
}

void PayloadUpdateImpl::activate(Side side, Persistence persistence) const
{
    ActivateRequest request;
    request.header.offset = 0;
    request.header.len = sizeof(request.activate);
    request.header.type = PAYLOAD_UPDATE_ACTIVATE;
    request.activate.half = static_cast<uint8_t>(side);
    request.activate.make_persistent = static_cast<uint8_t>(persistence);

    sendCommand(
        {reinterpret_cast<const uint8_t*>(&request), sizeof(ActivateRequest)});
}

std::optional<payload_update_confirm_response>
    PayloadUpdateImpl::confirm(enum payload_update_confirm_option option,
                               uint32_t timeout,
                               uint64_t confirmation_cookie) const
{

    ConfirmRequest request;
    request.header.offset = 0;
    request.header.len = sizeof(request.confirm);
    request.header.type = PAYLOAD_UPDATE_CONFIRM;
    request.confirm.option = option;
    request.confirm.timeout_value = boost::endian::native_to_little(timeout);
    request.confirm.confirmation_cookie =
        boost::endian::native_to_little(confirmation_cookie);

    std::vector<uint8_t> buf = hostCmd->sendCommand(
        EC_CMD_BOARD_SPECIFIC_BASE + EC_PRV_CMD_HOTH_PAYLOAD_UPDATE, 0,
        &request, sizeof(request));
    // Extract the response header out when returning the span
    std::span<const uint8_t> output = buf;
    auto rsp = stdplus::raw::extract<RspHeader>(output);
    if (rsp.result == HOTH_PAYLOAD_UPDATE_CONFIRM_NO_PENDING_PAYLOAD)
    {
        return std::nullopt;
    }

    if (rsp.result != EC_RES_SUCCESS)
    {
        stdplus::print(
            stderr,
            "Payload confirm command received a bad response from Hoth {:#x}\n",
            static_cast<uint8_t>(rsp.result));
        throw ResponseFailure();
    }

    return stdplus::raw::copyFrom<payload_update_confirm_response>(output);
}

namespace
{
// Helper functions for PayloadUpdateImpl::send
size_t SizeToSkip(std::span<const uint8_t> data)
{
    size_t i;
    for (i = 0; i < data.size(); i++)
    {
        if (data[i] != 0xff)
        {
            break;
        }
    }
    return i;
}

size_t SizeToSend(std::span<const uint8_t> data)
{
    size_t i;
    for (i = data.size(); i > 0; i--)
    {
        if (data[i - 1] != 0xff)
        {
            break;
        }
    }
    return i;
}
} // namespace

void PayloadUpdateImpl::send(const std::string& path) const
{
    Fd fd(sys->open(path.c_str(), O_RDONLY), sys);

    if (*fd < 0)
    {
        (void)fd.release();
        throw errnoException(std::format("Failed to open file {}", path));
    }

    std::array<uint8_t, max_packet_size> readBuffer;
    uint32_t offset = 0;
    ssize_t actualReadSize = 0;
    // Read and send payload until we reach EOF of the given file
    do
    {
        actualReadSize = sys->read(*fd, readBuffer.data(), max_packet_size);

        if (actualReadSize < 0)
        {
            throw errnoException(
                std::format("Failed to read from file {}", path));
        }
        if (actualReadSize > 0) {
            // Decided not to use initializer list to create the span here as
            // actualReadSize is ssize_t and we'd need to static_cast
            trimAndSend(std::span<uint8_t>(readBuffer.data(), actualReadSize),
                        offset);
            offset += actualReadSize;
        }
        // actualReadSize will be 0 when EOF is reached, exit loop
    } while (actualReadSize);
}

/* Parse and send the given data after trimming 0xff from the front and back
 * - This works because PayloadUpdateImpl::Initiate erased the
 * EEPROM to 0xff.
 * - This is also more efficient than sending everything, as our
 * image binaries tend to have large sections of 0xff and we can
 * avoid sending those sections.
 */
void PayloadUpdateImpl::trimAndSend(std::span<const uint8_t> data,
                                    uint32_t globalOffset) const
{
    // Allocate the payload buffer at "buffer".
    // "request" will point to the payload_update_packet section of the buffer
    // "request_payload" will point to the beginning of the payload
    // (after the payload_update_packet header).
    std::array<uint8_t, sizeof(payload_update_packet) + max_packet_size> buffer;
    payload_update_packet* request =
        reinterpret_cast<payload_update_packet*>(buffer.data());
    uint8_t* request_payload = &buffer[sizeof(payload_update_packet)];

    const size_t dataSize = data.size();
    if (dataSize > max_packet_size)
    {
        throw errnoException(
            "data to send cannot be bigger than max_packet_size");
    }
    size_t localOffset = SizeToSkip(data);
    if (localOffset >= dataSize)
    {
        // No need to send any payload
        return;
    }
    size_t max_size_to_send = std::min(dataSize - localOffset, max_packet_size);
    size_t size_to_send =
        SizeToSend(data.subspan(localOffset, max_size_to_send));

    // Construct and send payload
    request->offset = globalOffset + localOffset;
    request->len = size_to_send;
    request->type = PAYLOAD_UPDATE_CONTINUE;
    memcpy(request_payload, &data[localOffset], size_to_send);
    sendCommand({buffer.data(), sizeof(*request) + size_to_send});
}

void PayloadUpdateImpl::sendCommand(uint8_t command, uint32_t offset,
                                    uint32_t len) const
{
    std::vector<uint8_t> buf;
    (void)sendCommand(buf, command, offset, len);
}

void PayloadUpdateImpl::sendCommand(std::span<const uint8_t> request) const
{
    std::vector<uint8_t> buf;
    (void)sendCommand(buf, request);
}

[[nodiscard]] std::span<const uint8_t>
    PayloadUpdateImpl::sendCommand(std::vector<uint8_t>& buf, uint8_t command,
                                   uint32_t offset, uint32_t len) const
{
    // For most basic commands, request offset and length are zero
    payload_update_packet request;
    request.offset = offset;
    request.len = len;
    request.type = command;
    return sendCommand(buf, {reinterpret_cast<const uint8_t*>(&request),
                             sizeof(payload_update_packet)});
}

[[nodiscard]] std::span<const uint8_t>
    PayloadUpdateImpl::sendCommand(std::vector<uint8_t>& buf,
                                   std::span<const uint8_t> request) const
{
    buf = hostCmd->sendCommand(EC_CMD_BOARD_SPECIFIC_BASE +
                                   EC_PRV_CMD_HOTH_PAYLOAD_UPDATE,
                               0, request.data(), request.size());
    // Extract the response header out when returning the span
    std::span<const uint8_t> output = buf;
    auto rsp = stdplus::raw::extract<RspHeader>(output);
    if (rsp.result != EC_RES_SUCCESS)
    {
        stdplus::print(
            stderr, "Payload command received a bad response from Hoth {:#x}\n",
            static_cast<uint8_t>(rsp.result));
        throw ResponseFailure();
    }

    return output;
}

} // namespace internal

} // namespace hoth

} // namespace google
