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

const std::vector<uint8_t> extendedUserDataSection{
    // Header
    0x45, 0x44, 0x00, 0x18, 0x01, 0x02, 0x20, 0x00,

    // Creator ID 'O', and then data
    0x4F, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
    0x05, 0x0A, 0x0B, 0x0C};

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.insert(data.end(), extendedUserDataSection.begin(),
                        extendedUserDataSection.end());
            data.at(sectionCountOffset) = 7;
            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());
            break;
        case TestPELType::extendedUserDataSection:
            data.insert(data.end(), extendedUserDataSection.begin(),
                        extendedUserDataSection.end());
            break;
    }
    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;
}
