/*
// Copyright (c) 2019 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 <boost/algorithm/string/join.hpp>
#include <phosphor-logging/log.hpp>
#include <storagecommands.hpp>

namespace intel_oem::ipmi::sel
{
bool checkRedfishHooks(uint16_t recordID, uint8_t recordType,
                       uint32_t timestamp, uint16_t generatorID, uint8_t evmRev,
                       uint8_t sensorType, uint8_t sensorNum, uint8_t eventType,
                       uint8_t eventData1, uint8_t eventData2,
                       uint8_t eventData3);
bool checkRedfishHooks(uint16_t generatorID, uint8_t evmRev, uint8_t sensorType,
                       uint8_t sensorNum, uint8_t eventType, uint8_t eventData1,
                       uint8_t eventData2, uint8_t eventData3);
namespace redfish_hooks
{
struct SELData
{
    int generatorID;
    int sensorNum;
    int eventType;
    int offset;
    int eventData2;
    int eventData3;
};

enum class BIOSSensors
{
    memoryRASConfigStatus = 0x02,
    biosPOSTError = 0x06,
    intelUPILinkWidthReduced = 0x09,
    memoryRASModeSelect = 0x12,
    bootEvent = 0x83,
};

enum class BIOSSMISensors
{
    mirroringRedundancyState = 0x01,
    memoryECCError = 0x02,
    legacyPCIError = 0x03,
    pcieFatalError = 0x04,
    pcieCorrectableError = 0x05,
    sparingRedundancyState = 0x11,
    memoryParityError = 0x13,
    pcieFatalError2 = 0x14,
    biosRecovery = 0x15,
    adddcError = 0x20,
};

enum class BIOSEventTypes
{
    digitalDiscrete = 0x09,
    discreteRedundancyStates = 0x0b,
    sensorSpecificOffset = 0x6f,
    oemDiscrete0 = 0x70,
    oemDiscrete1 = 0x71,
    oemDiscrete6 = 0x76,
    oemDiscrete7 = 0x77,
    reservedA0 = 0xa0,
    reservedF0 = 0xf0,
};

static inline bool defaultMessageHook(const std::string& ipmiRaw)
{
    // Log the record as a default Redfish message instead of a SEL record

    static const std::string openBMCMessageRegistryVersion("0.1");
    std::string messageID = "OpenBMC." + openBMCMessageRegistryVersion +
                            ".SELEntryAdded";

    std::vector<std::string> messageArgs;
    messageArgs.push_back(ipmiRaw);

    // Log the Redfish message to the journal with the appropriate metadata
    std::string journalMsg = "SEL Entry Added: " + ipmiRaw;
    std::string messageArgsString = boost::algorithm::join(messageArgs, ",");
    phosphor::logging::log<phosphor::logging::level::INFO>(
        journalMsg.c_str(),
        phosphor::logging::entry("REDFISH_MESSAGE_ID=%s", messageID.c_str()),
        phosphor::logging::entry("REDFISH_MESSAGE_ARGS=%s",
                                 messageArgsString.c_str()));

    return true;
}

} // namespace redfish_hooks
} // namespace intel_oem::ipmi::sel
