// 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(fs::path&& directory, size_t blockSize, size_t pnorSize) :
    szBytes(sizeof(pnor_partition_table)), directory(std::move(directory)),
    numParts(0), blockSize(blockSize), pnorSize(pnorSize)
{
    preparePartitions();
    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()
{
    fs::path tocFile = directory;
    tocFile /= 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 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 = directory / part.data.name;
        if (!fs::exists(file))
        {
            std::stringstream err;
            err << "Partition file " << file.native() << " does not exist";
            throw InvalidTocEntry(err.str());
        }

        ++numParts;
    }
}

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

    for (decltype(numParts) i{}; i < numParts; ++i)
    {
        if ((offt >= table.partitions[i].data.base) &&
            (offt <
             (table.partitions[i].data.base + table.partitions[i].data.size)))
        {
            return table.partitions[i];
        }
    }

    MSG_ERR("Partition corresponding to offset 0x%zx not found", offset);
    elog<InternalFailure>();

    static pnor_partition p{};
    return p;
}

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];
        }
    }

    MSG_ERR("Partition '%s' not found", name.c_str());
    elog<InternalFailure>();
    static pnor_partition p{};
    return p;
}

} // 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;

    // If a a patch partition file exists, populate actual size with its file
    // size if it is smaller than the total size.
    fs::path patchFile(PARTITION_FILES_PATCH_LOC);
    patchFile /= part.data.name;
    if (fs::is_regular_file(patchFile))
    {
        part.data.actual =
            std::min(size, static_cast<size_t>(fs::file_size(patchFile)));
    }
    else
    {
        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
