// SPDX-License-Identifier: Apache-2.0
// Copyright (C) 2018 IBM Corp.
#include "pnor_partition_table.hpp"
#include "common.h"
#include "config.h"
#include "xyz/openbmc_project/Common/error.hpp"
#include <phosphor-logging/elog-errors.hpp>
#include <syslog.h>
#include <endian.h>
#include <regex>
#include <fstream>
#include <algorithm>

namespace openpower
{
namespace virtual_pnor
{

using namespace phosphor::logging;
using namespace sdbusplus::xyz::openbmc_project::Common::Error;

namespace partition
{

Table::Table(const struct mbox_context* ctx) :
    szBytes(sizeof(pnor_partition_table)), numParts(0),
    blockSize(1 << ctx->erase_size_shift), pnorSize(ctx->flash_size)
{
    preparePartitions(ctx);
    prepareHeader();
    hostTbl = endianFixup(tbl);
}

void Table::prepareHeader()
{
    decltype(auto) table = getNativeTable();
    table.data.magic = PARTITION_HEADER_MAGIC;
    table.data.version = PARTITION_VERSION_1;
    table.data.size = blocks();
    table.data.entry_size = sizeof(pnor_partition);
    table.data.entry_count = numParts;
    table.data.block_size = blockSize;
    table.data.block_count = pnorSize / blockSize;
    table.checksum = details::checksum(table.data);
}

inline void Table::allocateMemory(const fs::path& tocFile)
{
    size_t num = 0;
    std::string line;
    std::ifstream file(tocFile.c_str());

    // Find number of lines in partition file - this will help
    // determine the number of partitions and hence also how much
    // memory to allocate for the partitions array.
    // The actual number of partitions may turn out to be lesser than this,
    // in case of errors.
    while (std::getline(file, line))
    {
        // Check if line starts with "partition"
        if (std::string::npos != line.find("partition", 0))
        {
            ++num;
        }
    }

    szBytes = sizeof(pnor_partition_table) + (num * sizeof(pnor_partition));
    tbl.resize(capacity());
}

void Table::preparePartitions(const struct mbox_context* ctx)
{
    const fs::path roDir = ctx->paths.ro_loc;
    const fs::path patchDir = ctx->paths.patch_loc;
    fs::path tocFile = roDir / PARTITION_TOC_FILE;
    allocateMemory(tocFile);

    std::ifstream file(tocFile.c_str());
    std::string line;
    decltype(auto) table = getNativeTable();

    while (std::getline(file, line))
    {
        pnor_partition& part = table.partitions[numParts];
        fs::path patch;
        fs::path file;

        // The ToC file presented in the vpnor squashfs looks like:
        //
        // version=IBM-witherspoon-ibm-OP9_v1.19_1.135
        // extended_version=op-build-v1.19-571-g04f4690-dirty,buildroot-2017.11-5-g65679be,skiboot-v5.10-rc4,hostboot-4c46d66,linux-4.14.20-openpower1-p4a6b675,petitboot-v1.6.6-pe5aaec2,machine-xml-0fea226,occ-3286b6b,hostboot-binaries-3d1af8f,capp-ucode-p9-dd2-v3,sbe-99e2fe2
        // partition00=part,0x00000000,0x00002000,00,READWRITE
        // partition01=HBEL,0x00008000,0x0002c000,00,ECC,REPROVISION,CLEARECC,READWRITE
        // ...
        //
        // As such we want to skip any lines that don't begin with 'partition'
        if (std::string::npos == line.find("partition", 0))
        {
            continue;
        }

        parseTocLine(line, blockSize, part);

        if (numParts > 0)
        {
            struct pnor_partition& prev = table.partitions[numParts - 1];
            uint32_t prev_end = prev.data.base + prev.data.size;

            if (part.data.id == prev.data.id)
            {
                MSG_ERR("ID for previous partition '%s' at block 0x%" PRIx32
                        "matches current partition '%s' at block 0x%" PRIx32
                        ": %" PRId32 "\n",
                        prev.data.name, prev.data.base, part.data.name,
                        part.data.base, part.data.id);
            }

            if (part.data.base < prev_end)
            {
                std::stringstream err;
                err << "Partition '" << part.data.name << "' start block 0x"
                    << std::hex << part.data.base << "is less than the end "
                    << "block 0x" << std::hex << prev_end << " of '"
                    << prev.data.name << "'";
                throw InvalidTocEntry(err.str());
            }
        }

        file = roDir / part.data.name;
        if (!fs::exists(file))
        {
            std::stringstream err;
            err << "Partition file " << file.native() << " does not exist";
            throw InvalidTocEntry(err.str());
        }

        patch = patchDir / part.data.name;
        if (fs::is_regular_file(patch))
        {
            const size_t size = part.data.size * blockSize;
            part.data.actual =
                std::min(size, static_cast<size_t>(fs::file_size(patch)));
        }

        ++numParts;
    }
}

const pnor_partition& Table::partition(size_t offset) const
{
    const decltype(auto) table = getNativeTable();
    size_t blockOffset = offset / blockSize;

    for (decltype(numParts) i{}; i < numParts; ++i)
    {
        const struct pnor_partition& part = table.partitions[i];
        size_t len = part.data.size;

        if ((blockOffset >= part.data.base) &&
            (blockOffset < (part.data.base + len)))
        {
            return part;
        }

        /* Are we in a hole between partitions? */
        if (blockOffset < part.data.base)
        {
            throw UnmappedOffset(offset, part.data.base * blockSize);
        }
    }

    throw UnmappedOffset(offset, pnorSize);
}

const pnor_partition& Table::partition(const std::string& name) const
{
    const decltype(auto) table = getNativeTable();

    for (decltype(numParts) i{}; i < numParts; ++i)
    {
        if (name == table.partitions[i].data.name)
        {
            return table.partitions[i];
        }
    }

    std::stringstream err;
    err << "Partition " << name << " is not listed in the table of contents";
    throw UnknownPartition(err.str());
}

} // namespace partition

PartitionTable endianFixup(const PartitionTable& in)
{
    PartitionTable out;
    out.resize(in.size());
    auto src = reinterpret_cast<const pnor_partition_table*>(in.data());
    auto dst = reinterpret_cast<pnor_partition_table*>(out.data());

    dst->data.magic = htobe32(src->data.magic);
    dst->data.version = htobe32(src->data.version);
    dst->data.size = htobe32(src->data.size);
    dst->data.entry_size = htobe32(src->data.entry_size);
    dst->data.entry_count = htobe32(src->data.entry_count);
    dst->data.block_size = htobe32(src->data.block_size);
    dst->data.block_count = htobe32(src->data.block_count);
    dst->checksum = details::checksum(dst->data);

    for (decltype(src->data.entry_count) i{}; i < src->data.entry_count; ++i)
    {
        auto psrc = &src->partitions[i];
        auto pdst = &dst->partitions[i];
        strncpy(pdst->data.name, psrc->data.name, PARTITION_NAME_MAX);
        // Just to be safe
        pdst->data.name[PARTITION_NAME_MAX] = '\0';
        pdst->data.base = htobe32(psrc->data.base);
        pdst->data.size = htobe32(psrc->data.size);
        pdst->data.pid = htobe32(psrc->data.pid);
        pdst->data.id = htobe32(psrc->data.id);
        pdst->data.type = htobe32(psrc->data.type);
        pdst->data.flags = htobe32(psrc->data.flags);
        pdst->data.actual = htobe32(psrc->data.actual);
        for (size_t j = 0; j < PARTITION_USER_WORDS; ++j)
        {
            pdst->data.user.data[j] = htobe32(psrc->data.user.data[j]);
        }
        pdst->checksum = details::checksum(pdst->data);
    }

    return out;
}

static inline void writeSizes(pnor_partition& part, size_t start, size_t end,
                              size_t blockSize)
{
    size_t size = end - start;
    part.data.base = align_up(start, blockSize) / blockSize;
    size_t sizeInBlocks = align_up(size, blockSize) / blockSize;
    part.data.size = sizeInBlocks;
    part.data.actual = size;
}

static inline void writeUserdata(pnor_partition& part, uint32_t version,
                                 const std::string& data)
{
    std::istringstream stream(data);
    std::string flag{};
    auto perms = 0;
    auto state = 0;

    MSG_DBG("Parsing ToC flags '%s'\n", data.c_str());
    while (std::getline(stream, flag, ','))
    {
        if (flag == "")
            continue;

        if (flag == "ECC")
        {
            state |= PARTITION_ECC_PROTECTED;
        }
        else if (flag == "READONLY")
        {
            perms |= PARTITION_READONLY;
        }
        else if (flag == "READWRITE")
        {
            perms &= ~PARTITION_READONLY;
        }
        else if (flag == "PRESERVED")
        {
            perms |= PARTITION_PRESERVED;
        }
        else if (flag == "REPROVISION")
        {
            perms |= PARTITION_REPROVISION;
        }
        else if (flag == "VOLATILE")
        {
            perms |= PARTITION_VOLATILE;
        }
        else if (flag == "CLEARECC")
        {
            perms |= PARTITION_CLEARECC;
        }
        else
        {
            MSG_INFO("Found unimplemented partition property: %s\n",
                     flag.c_str());
        }
    }

    part.data.user.data[0] = state;
    part.data.user.data[1] = perms;
    part.data.user.data[1] |= version;
}

static inline void writeDefaults(pnor_partition& part)
{
    part.data.pid = PARENT_PATITION_ID;
    part.data.type = PARTITION_TYPE_DATA;
    part.data.flags = 0; // flags unused
}

static inline void writeNameAndId(pnor_partition& part, std::string&& name,
                                  const std::string& id)
{
    name.resize(PARTITION_NAME_MAX);
    memcpy(part.data.name, name.c_str(), sizeof(part.data.name));
    part.data.id = std::stoul(id);
}

void parseTocLine(const std::string& line, size_t blockSize,
                  pnor_partition& part)
{
    static constexpr auto ID_MATCH = 1;
    static constexpr auto NAME_MATCH = 2;
    static constexpr auto START_ADDR_MATCH = 4;
    static constexpr auto END_ADDR_MATCH = 6;
    static constexpr auto VERSION_MATCH = 8;
    constexpr auto versionShift = 24;

    // Parse PNOR toc (table of contents) file, which has lines like :
    // partition01=HBB,0x00010000,0x000a0000,0x80,ECC,PRESERVED, to indicate
    // partition information
    std::regex regex{
        "^partition([0-9]+)=([A-Za-z0-9_]+),"
        "(0x)?([0-9a-fA-F]+),(0x)?([0-9a-fA-F]+),(0x)?([A-Fa-f0-9]{2})",
        std::regex::extended};

    std::smatch match;
    if (!std::regex_search(line, match, regex))
    {
        std::stringstream err;
        err << "Malformed partition description: " << line.c_str() << "\n";
        throw MalformedTocEntry(err.str());
    }

    writeNameAndId(part, match[NAME_MATCH].str(), match[ID_MATCH].str());
    writeDefaults(part);

    unsigned long start =
        std::stoul(match[START_ADDR_MATCH].str(), nullptr, 16);
    if (start & (blockSize - 1))
    {
        MSG_ERR("Start offset 0x%lx for partition '%s' is not aligned to block "
                "size 0x%zx\n",
                start, match[NAME_MATCH].str().c_str(), blockSize);
    }

    unsigned long end = std::stoul(match[END_ADDR_MATCH].str(), nullptr, 16);
    if ((end - start) & (blockSize - 1))
    {
        MSG_ERR("Partition '%s' has a size 0x%lx that is not aligned to block "
                "size 0x%zx\n",
                match[NAME_MATCH].str().c_str(), (end - start), blockSize);
    }

    if (start >= end)
    {
        std::stringstream err;
        err << "Partition " << match[NAME_MATCH].str()
            << " has an invalid range: start offset (0x" << std::hex << start
            << " is beyond open end (0x" << std::hex << end << ")\n";
        throw InvalidTocEntry(err.str());
    }
    writeSizes(part, start, end, blockSize);

    // Use the shift to convert "80" to 0x80000000
    unsigned long version = std::stoul(match[VERSION_MATCH].str(), nullptr, 16);
    writeUserdata(part, version << versionShift, match.suffix().str());
    part.checksum = details::checksum(part.data);
}

} // namespace virtual_pnor
} // namespace openpower
