/**
 * Copyright © 2019 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 "pel_utils.hpp"

#include "extensions/openpower-pels/private_header.hpp"
#include "extensions/openpower-pels/user_header.hpp"

#include <fstream>

#include <gtest/gtest.h>

namespace fs = std::filesystem;
using namespace openpower::pels;

std::filesystem::path CleanLogID::pelIDFile{};
std::filesystem::path CleanPELFiles::pelIDFile{};
std::filesystem::path CleanPELFiles::repoPath{};
std::filesystem::path CleanPELFiles::registryPath{};

const std::vector<uint8_t> privateHeaderSection{
    // section header
    0x50, 0x48, // ID 'PH'
    0x00, 0x30, // Size
    0x01, 0x02, // version, subtype
    0x03, 0x04, // comp ID

    0x20, 0x30, 0x05, 0x09, 0x11, 0x1E, 0x1,  0x63, // create timestamp
    0x20, 0x31, 0x06, 0x0F, 0x09, 0x22, 0x3A, 0x00, // commit timestamp
    0x4F,                                           // creatorID 'O'
    0x00,                                           // logtype
    0x00,                                           // reserved
    0x02,                                           // section count
    0x90, 0x91, 0x92, 0x93,                         // OpenBMC log ID
    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0,    // creator version
    0x50, 0x51, 0x52, 0x53,                         // plid
    0x80, 0x81, 0x82, 0x83};                        // PEL ID

const std::vector<uint8_t> userHeaderSection{
    // section header
    0x55, 0x48, // ID 'UH'
    0x00, 0x18, // Size
    0x01, 0x0A, // version, subtype
    0x0B, 0x0C, // comp ID

    0x10, 0x04,             // subsystem, scope
    0x20, 0x00,             // severity, type
    0x00, 0x00, 0x00, 0x00, // reserved
    0x03, 0x04,             // problem domain, vector
    0x80, 0xC0,             // action flags
    0x00, 0x00, 0x00, 0x00  // reserved
};

const std::vector<uint8_t> srcSectionNoCallouts{

    // Header
    'P', 'S', 0x00, 0x50, 0x01, 0x01, 0x02, 0x02,

    0x02, 0x00, 0x00, // version, flags, reserved
    0x09, 0x00, 0x00, // hex word count, reserved2B
    0x00, 0x48,       // SRC structure size

    // Hex words 2 - 9
    0x02, 0x02, 0x02, 0x55, 0x03, 0x03, 0x03, 0x10, 0x04, 0x04, 0x04, 0x04,
    0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07,
    0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09,
    // ASCII string
    'B', 'D', '8', 'D', '5', '6', '7', '8', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
    ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
    ' ', ' '};

const std::vector<uint8_t> failingMTMSSection{
    // Header
    0x4D, 0x54, 0x00, 0x1C, 0x01, 0x00, 0x20, 0x00,

    'T',  'T',  'T',  'T',  '-',  'M',  'M',  'M',  '1', '2',
    '3',  '4',  '5',  '6',  '7',  '8',  '9',  'A',  'B', 'C'};

const std::vector<uint8_t> UserDataSection{
    // Header
    0x55, 0x44, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00,

    0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};

const std::vector<uint8_t> ExtUserHeaderSection{
    // Header
    'E', 'H', 0x00, 0x60, 0x01, 0x00, 0x03, 0x04,

    // MTMS
    'T', 'T', 'T', 'T', '-', 'M', 'M', 'M', '1', '2', '3', '4', '5', '6', '7',
    '8', '9', 'A', 'B', 'C',

    // Server FW version
    'S', 'E', 'R', 'V', 'E', 'R', '_', 'V', 'E', 'R', 'S', 'I', 'O', 'N', '\0',
    '\0',

    // Subsystem FW Version
    'B', 'M', 'C', '_', 'V', 'E', 'R', 'S', 'I', 'O', 'N', '\0', '\0', '\0',
    '\0', '\0',

    0x00, 0x00, 0x00, 0x00,                         // Reserved
    0x20, 0x25, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, // Ref time
    0x00, 0x00, 0x00,                               // Reserved

    // SymptomID length and symptom ID
    20, 'B', 'D', '8', 'D', '4', '2', '0', '0', '_', '1', '2', '3', '4', '5',
    '6', '7', '8', '\0', '\0', '\0'};

const std::vector<uint8_t> srcFRUIdentityCallout{
    'I', 'D', 0x1C, 0x1D,                     // type, size, flags
    '1', '2', '3',  '4',                      // PN
    '5', '6', '7',  0x00, 'A', 'A', 'A', 'A', // CCIN
    '1', '2', '3',  '4',  '5', '6', '7', '8', // SN
    '9', 'A', 'B',  'C'};

const std::vector<uint8_t> srcPCEIdentityCallout{
    'P', 'E', 0x24, 0x00,                      // type, size, flags
    'T', 'T', 'T',  'T',  '-', 'M', 'M',  'M', // MTM
    '1', '2', '3',  '4',  '5', '6', '7',       // SN
    '8', '9', 'A',  'B',  'C', 'P', 'C',  'E', // Name + null padded
    'N', 'A', 'M',  'E',  '1', '2', 0x00, 0x00, 0x00};

const std::vector<uint8_t> srcMRUCallout{
    'M',  'R',  0x28, 0x04, // ID, size, flags
    0x00, 0x00, 0x00, 0x00, // Reserved
    0x00, 0x00, 0x00, 'H',  // priority 0
    0x01, 0x01, 0x01, 0x01, // MRU ID 0
    0x00, 0x00, 0x00, 'M',  // priority 1
    0x02, 0x02, 0x02, 0x02, // MRU ID 1
    0x00, 0x00, 0x00, 'L',  // priority 2
    0x03, 0x03, 0x03, 0x03, // MRU ID 2
    0x00, 0x00, 0x00, 'H',  // priority 3
    0x04, 0x04, 0x04, 0x04, // MRU ID 3
};

constexpr size_t sectionCountOffset = 27;
constexpr size_t createTimestampPHOffset = 8;
constexpr size_t commitTimestampPHOffset = 16;
constexpr size_t creatorPHOffset = 24;
constexpr size_t obmcIDPHOffset = 28;
constexpr size_t plidPHOffset = 40;
constexpr size_t pelIDPHOffset = 44;
constexpr size_t sevUHOffset = 10;
constexpr size_t actionFlagsUHOffset = 18;

std::vector<uint8_t> pelDataFactory(TestPELType type)
{
    std::vector<uint8_t> data;

    switch (type)
    {
        case TestPELType::pelSimple:
            data.insert(data.end(), privateHeaderSection.begin(),
                        privateHeaderSection.end());
            data.insert(data.end(), userHeaderSection.begin(),
                        userHeaderSection.end());
            data.insert(data.end(), srcSectionNoCallouts.begin(),
                        srcSectionNoCallouts.end());
            data.insert(data.end(), failingMTMSSection.begin(),
                        failingMTMSSection.end());
            data.insert(data.end(), UserDataSection.begin(),
                        UserDataSection.end());
            data.insert(data.end(), ExtUserHeaderSection.begin(),
                        ExtUserHeaderSection.end());
            data.at(sectionCountOffset) = 6;
            break;
        case TestPELType::privateHeaderSection:
            data.insert(data.end(), privateHeaderSection.begin(),
                        privateHeaderSection.end());
            break;
        case TestPELType::userHeaderSection:
            data.insert(data.end(), userHeaderSection.begin(),
                        userHeaderSection.end());
            break;
        case TestPELType::primarySRCSection:
            data.insert(data.end(), srcSectionNoCallouts.begin(),
                        srcSectionNoCallouts.end());
            break;
        case TestPELType::primarySRCSection2Callouts:
        {
            // Start with the no-callouts SRC, and add the callouts section
            // from above.
            auto src = srcSectionNoCallouts;
            auto callouts =
                srcDataFactory(TestSRCType::calloutSection2Callouts);

            src.insert(src.end(), callouts.begin(), callouts.end());

            // Set the flag that says there are callouts
            // One byte after the 8B header
            src[8 + 1] |= 0x01;

            // Set the new sizes
            uint16_t size = src.size();
            Stream stream{src};

            stream.offset(2); // In the header
            stream << size;

            // In the SRC - the size field doesn't include the header
            size -= 8;
            stream.offset(8 + 6);
            stream << size;

            data.insert(data.end(), src.begin(), src.end());
            break;
        }
        case TestPELType::failingMTMSSection:
            data.insert(data.end(), failingMTMSSection.begin(),
                        failingMTMSSection.end());
    }
    return data;
}

std::vector<uint8_t> pelFactory(uint32_t id, char creatorID, uint8_t severity,
                                uint16_t actionFlags, size_t size)
{
    std::vector<uint8_t> data;
    size_t offset = 0;

    auto now = std::chrono::system_clock::now();
    auto timestamp = getBCDTime(now);

    // Start with the default Private Header, and modify it
    data.insert(data.end(), privateHeaderSection.begin(),
                privateHeaderSection.end());
    data.at(creatorPHOffset) = creatorID;

    // Modify the multibyte fields in it
    Stream stream{data};
    stream.offset(createTimestampPHOffset);
    stream << timestamp;
    stream.offset(commitTimestampPHOffset);
    stream << timestamp;
    stream.offset(plidPHOffset);
    stream << id;
    stream.offset(pelIDPHOffset);
    stream << id;
    stream.offset(obmcIDPHOffset);
    stream << id + 500;

    offset = data.size();

    // User Header
    data.insert(data.end(), userHeaderSection.begin(), userHeaderSection.end());
    data.at(offset + sevUHOffset) = severity;
    data.at(offset + actionFlagsUHOffset) = actionFlags >> 8;
    data.at(offset + actionFlagsUHOffset + 1) = actionFlags;

    // Use the default SRC, failing MTMS, and ext user Header sections
    auto src = pelDataFactory(TestPELType::primarySRCSection2Callouts);

    data.insert(data.end(), src.begin(), src.end());
    data.insert(data.end(), failingMTMSSection.begin(),
                failingMTMSSection.end());
    data.insert(data.end(), ExtUserHeaderSection.begin(),
                ExtUserHeaderSection.end());

    data.at(sectionCountOffset) = 5;

    // Require the size to be enough for all the above sections.
    assert(size >= data.size());
    assert(size <= 16384);

    // Add a UserData section to get the size we need.
    auto udSection = UserDataSection;
    udSection.resize(size - data.size());

    if (!udSection.empty())
    {
        // At least has to be 8B for the header
        assert(udSection.size() >= 8);

        // UD sections must be 4B aligned
        assert(udSection.size() % 4 == 0);

        // Set the new size in the section heder
        Stream udStream{udSection};
        udStream.offset(2);
        udStream << static_cast<uint16_t>(udSection.size());

        data.insert(data.end(), udSection.begin(), udSection.end());
        data[sectionCountOffset]++;
    }

    assert(size == data.size());
    return data;
}

std::vector<uint8_t> srcDataFactory(TestSRCType type)
{
    switch (type)
    {
        case TestSRCType::fruIdentityStructure:
            return srcFRUIdentityCallout;

        case TestSRCType::pceIdentityStructure:
            return srcPCEIdentityCallout;

        case TestSRCType::mruStructure:
            return srcMRUCallout;

        case TestSRCType::calloutStructureA:
        {
            // Add just the FRU identity substructure to the base structure
            std::vector<uint8_t> data{
                0xFF, 0x28, 'H', 4,   // size, flags, priority, LC length
                'U',  '4',  '2', 0x00 // LC
            };

            data.insert(data.end(), srcFRUIdentityCallout.begin(),
                        srcFRUIdentityCallout.end());

            // The final size
            data[0] = data.size();
            return data;
        }
        case TestSRCType::calloutStructureB:
        {
            // Add all 3 substructures to the base structure

            std::vector<uint8_t> data{
                0xFF, 0x2F, 'L', 8, // size, flags, priority, LC length
                'U',  '1',  '2', '-', 'P', '1', 0x00, 0x00 // LC
            };
            data.insert(data.end(), srcFRUIdentityCallout.begin(),
                        srcFRUIdentityCallout.end());
            data.insert(data.end(), srcPCEIdentityCallout.begin(),
                        srcPCEIdentityCallout.end());
            data.insert(data.end(), srcMRUCallout.begin(), srcMRUCallout.end());

            // The final size
            data[0] = data.size();
            return data;
        }
        case TestSRCType::calloutSection2Callouts:
        {
            std::vector<uint8_t> data{0xC0, 0x00, 0x00,
                                      0x00}; // ID, flags, length in words

            // Add 2 callouts
            auto callout = srcDataFactory(TestSRCType::calloutStructureA);
            data.insert(data.end(), callout.begin(), callout.end());

            callout = srcDataFactory(TestSRCType::calloutStructureB);
            data.insert(data.end(), callout.begin(), callout.end());

            // Set the actual word length value at offset 2
            Stream stream{data};
            uint16_t wordLength = data.size() / 4;
            stream.offset(2);
            stream << wordLength;
            stream.offset(0);

            return data;
        }
    }
    return {};
}

std::unique_ptr<std::vector<uint8_t>> readPELFile(const fs::path& path)
{
    std::ifstream file{path};

    auto pel = std::make_unique<std::vector<uint8_t>>(
        std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>());
    return pel;
}
