/*
// Copyright (c) 2018 Intel 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.
*/

#pragma once

#include <phosphor-logging/elog-errors.hpp>

#include <array>

static constexpr const char* mdrType2File = "/var/lib/smbios/smbios2";
static constexpr const char* smbiosPath = "/var/lib/smbios";

static constexpr uint16_t mdrSMBIOSSize = 32 * 1024;

constexpr uint16_t smbiosAgentId = 0x0101;
constexpr int firstAgentIndex = 1;

constexpr uint8_t maxDirEntries = 4;
constexpr uint32_t mdr2SMSize = 0x00100000;
constexpr uint32_t mdr2SMBaseAddress = 0x9FF00000;

constexpr uint8_t mdrDirVersion = 1;
constexpr uint8_t mdrTypeII = 2;

constexpr uint8_t mdr2Version = 2;
constexpr uint8_t smbiosAgentVersion = 1;
constexpr uint8_t smbiosDirVersion = 1;

constexpr uint32_t pageMask = 0xf000;
constexpr int smbiosDirIndex = 0;

constexpr uint32_t smbiosTableVersion = 15;
constexpr uint32_t smbiosTableTimestamp = 0x45464748;
constexpr uint32_t smbiosSMMemoryOffset = 0;
constexpr uint32_t smbiosSMMemorySize = 1024 * 1024;
constexpr uint32_t smbiosTableStorageSize = 64 * 1024;
constexpr uint32_t defaultTimeout = 20000;

enum class MDR2SMBIOSStatusEnum
{
    mdr2Init = 0,
    mdr2Loaded = 1,
    mdr2Updated = 2,
    mdr2Updating = 3
};

enum class MDR2DirLockEnum
{
    mdr2DirUnlock = 0,
    mdr2DirLock = 1
};

enum class DirDataRequestEnum
{
    dirDataNotRequested = 0x00,
    dirDataRequested = 0x01
};

enum class FlagStatus
{
    flagIsInvalid = 0,
    flagIsValid = 1,
    flagIsLocked = 2
};

typedef struct
{
    uint8_t dataInfo[16];
} DataIdStruct;

typedef struct
{
    DataIdStruct id;
    uint32_t size;
    uint32_t dataSetSize;
    uint8_t dataVersion;
    uint32_t timestamp;
} Mdr2DirEntry;

typedef struct
{
    Mdr2DirEntry common;
    MDR2SMBIOSStatusEnum stage;
    MDR2DirLockEnum lock;
    uint16_t lockHandle;
    uint32_t xferBuff;
    uint32_t xferSize;
    uint32_t maxDataSize;
    uint8_t* dataStorage;
} Mdr2DirLocalStruct;

typedef struct
{
    uint8_t agentVersion;
    uint8_t dirVersion;
    uint8_t dirEntries;
    uint8_t status; // valid / locked / etc
    uint8_t remoteDirVersion;
    uint16_t sessionHandle;
    Mdr2DirLocalStruct dir[maxDirEntries];
} Mdr2DirStruct;

struct MDRSMBIOSHeader
{
    uint8_t dirVer;
    uint8_t mdrType;
    uint32_t timestamp;
    uint32_t dataSize;
} __attribute__((packed));

typedef struct
{
    uint8_t majorVersion;
    uint8_t minorVersion;
} SMBIOSVersion;

struct EntryPointStructure21
{
    uint32_t anchorString;
    uint8_t epChecksum;
    uint8_t epLength;
    SMBIOSVersion smbiosVersion;
    uint16_t maxStructSize;
    uint8_t epRevision;
    uint8_t formattedArea[5];
    uint8_t intermediateAnchorString[5];
    uint8_t intermediateChecksum;
    uint16_t structTableLength;
    uint32_t structTableAddress;
    uint16_t noOfSmbiosStruct;
    uint8_t smbiosBDCRevision;
} __attribute__((packed));

struct EntryPointStructure30
{
    uint8_t anchorString[5];
    uint8_t epChecksum;
    uint8_t epLength;
    SMBIOSVersion smbiosVersion;
    uint8_t smbiosDocRev;
    uint8_t epRevision;
    uint8_t reserved;
    uint32_t structTableMaxSize;
    uint64_t structTableAddr;
} __attribute__((packed));

static constexpr const char* cpuPath =
    "/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu";

static constexpr const char* dimmPath =
    "/xyz/openbmc_project/inventory/system/chassis/motherboard/dimm";

static constexpr const char* pciePath =
    "/xyz/openbmc_project/inventory/system/chassis/motherboard/pcieslot";

static constexpr const char* systemPath =
    "/xyz/openbmc_project/inventory/system/chassis/motherboard/bios";

constexpr std::array<SMBIOSVersion, 3> supportedSMBIOSVersions{
    SMBIOSVersion{3, 2}, SMBIOSVersion{3, 3}, SMBIOSVersion{3, 5}};

typedef enum
{
    biosType = 0,
    systemType = 1,
    baseboardType = 2,
    chassisType = 3,
    processorsType = 4,
    memoryControllerType = 5,
    memoryModuleInformationType = 6,
    cacheType = 7,
    portConnectorType = 8,
    systemSlots = 9,
    onBoardDevicesType = 10,
    oemStringsType = 11,
    systemCconfigurationOptionsType = 12,
    biosLanguageType = 13,
    groupAssociatonsType = 14,
    systemEventLogType = 15,
    physicalMemoryArrayType = 16,
    memoryDeviceType = 17,
} SmbiosType;

static constexpr uint8_t separateLen = 2;

static inline uint8_t* smbiosNextPtr(uint8_t* smbiosDataIn)
{
    if (smbiosDataIn == nullptr)
    {
        return nullptr;
    }
    uint8_t* smbiosData = smbiosDataIn + *(smbiosDataIn + 1);
    int len = 0;
    while ((*smbiosData | *(smbiosData + 1)) != 0)
    {
        smbiosData++;
        len++;
        if (len >= mdrSMBIOSSize) // To avoid endless loop
        {
            return nullptr;
        }
    }
    return smbiosData + separateLen;
}

// When first time run getSMBIOSTypePtr, need to send the RegionS[].regionData
// to smbiosDataIn
static inline uint8_t* getSMBIOSTypePtr(uint8_t* smbiosDataIn, uint8_t typeId,
                                        size_t size = 0)
{
    if (smbiosDataIn == nullptr)
    {
        return nullptr;
    }
    char* smbiosData = reinterpret_cast<char*>(smbiosDataIn);
    while ((*smbiosData != '\0') || (*(smbiosData + 1) != '\0'))
    {
        uint32_t len = *(smbiosData + 1);
        if (*smbiosData != typeId)
        {
            smbiosData += len;
            while ((*smbiosData != '\0') || (*(smbiosData + 1) != '\0'))
            {
                smbiosData++;
                len++;
                if (len >= mdrSMBIOSSize) // To avoid endless loop
                {
                    return nullptr;
                }
            }
            smbiosData += separateLen;
            continue;
        }
        if (len < size)
        {
            phosphor::logging::log<phosphor::logging::level::ERR>(
                "Record size mismatch!");
            return nullptr;
        }
        return reinterpret_cast<uint8_t*>(smbiosData);
    }
    return nullptr;
}

static inline std::string positionToString(uint8_t positionNum,
                                           uint8_t structLen, uint8_t* dataIn)
{
    if (dataIn == nullptr || positionNum == 0)
    {
        return "";
    }
    uint16_t limit = mdrSMBIOSSize; // set a limit to avoid endless loop

    char* target = reinterpret_cast<char*>(dataIn + structLen);
    if (target == nullptr)
    {
        return "";
    }
    for (uint8_t index = 1; index < positionNum; index++)
    {
        for (; *target != '\0'; target++)
        {
            limit--;
            // When target = dataIn + structLen + limit,
            // following target++ will be nullptr
            if (limit < 1 || target == nullptr)
            {
                return "";
            }
        }
        target++;
        if (target == nullptr || *target == '\0')
        {
            return ""; // 0x00 0x00 means end of the entry.
        }
    }

    std::string result = target;
    return result;
}
