/**
 * 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 "user_header.hpp"

#include "json_utils.hpp"
#include "pel_types.hpp"
#include "pel_values.hpp"
#include "severity.hpp"

#include <phosphor-logging/lg2.hpp>

#include <format>
#include <iostream>

namespace openpower
{
namespace pels
{

namespace pv = openpower::pels::pel_values;

void UserHeader::unflatten(Stream& stream)
{
    stream >> _header >> _eventSubsystem >> _eventScope >> _eventSeverity >>
        _eventType >> _reserved4Byte1 >> _problemDomain >> _problemVector >>
        _actionFlags >> _states;
}

void UserHeader::flatten(Stream& stream) const
{
    stream << _header << _eventSubsystem << _eventScope << _eventSeverity
           << _eventType << _reserved4Byte1 << _problemDomain << _problemVector
           << _actionFlags << _states;
}

UserHeader::UserHeader(const message::Entry& entry,
                       phosphor::logging::Entry::Level severity,
                       const AdditionalData& additionalData,
                       const DataInterfaceBase& dataIface)
{
    _header.id = static_cast<uint16_t>(SectionID::userHeader);
    _header.size = UserHeader::flattenedSize();
    _header.version = userHeaderVersion;
    _header.subType = 0;
    _header.componentID = static_cast<uint16_t>(ComponentID::phosphorLogging);

    std::optional<uint8_t> subsys;

    // Check for additional data - PEL_SUBSYSTEM
    auto ss = additionalData.getValue("PEL_SUBSYSTEM");
    if (ss)
    {
        auto eventSubsystem = std::stoul(*ss, NULL, 16);
        std::string subsystemString = pv::getValue(eventSubsystem,
                                                   pel_values::subsystemValues);
        if (subsystemString == "invalid")
        {
            lg2::warning(
                "UH: Invalid SubSystem value in PEL_SUBSYSTEM: {PEL_SUBSYSTEM}",
                "PEL_SUBSYSTEM", lg2::hex, eventSubsystem);
        }
        else
        {
            subsys = eventSubsystem;
        }
    }
    else
    {
        subsys = entry.subsystem;
    }

    if (subsys)
    {
        _eventSubsystem = *subsys;
    }
    else
    {
        // Gotta use something, how about 'others'.
        lg2::warning(
            "No PEL subystem value supplied for error, using 'others'");
        _eventSubsystem = 0x70;
    }

    _eventScope = entry.eventScope.value_or(
        static_cast<uint8_t>(EventScope::entirePlatform));

    {
        bool mfgSevStatus = false;
        bool mfgActionFlagStatus = false;

        // Get the mfg severity & action flags
        if (entry.mfgSeverity || entry.mfgActionFlags)
        {
            std::optional<uint8_t> sev = std::nullopt;
            uint16_t val = 0;

            if (entry.mfgSeverity)
            {
                // Find the mf severity possibly dependent on the system type.
                sev = getSeverity(entry.mfgSeverity.value(), dataIface);
            }

            if (entry.mfgActionFlags)
            {
                // Find the mfg action flags
                val = entry.mfgActionFlags.value();
            }

            if (sev || val)
            {
                bool mfgProp = dataIface.getQuiesceOnError();
                if (mfgProp)
                {
                    if (sev)
                    {
                        _eventSeverity = *sev;
                        mfgSevStatus = true;
                    }

                    if (val)
                    {
                        _actionFlags = val;
                        mfgActionFlagStatus = true;
                    }
                }
            }
        }

        if (!mfgSevStatus)
        {
            // Get the severity from the registry if it's there, otherwise get
            // it from the OpenBMC event log severity value.
            if (!entry.severity)
            {
                _eventSeverity = convertOBMCSeverityToPEL(severity);
            }
            else
            {
                // Find the severity possibly dependent on the system type.
                auto sev = getSeverity(entry.severity.value(), dataIface);
                if (sev)
                {
                    _eventSeverity = *sev;
                }
                else
                {
                    // Either someone  screwed up the message registry
                    // or getSystemNames failed.
                    lg2::error(
                        "Failed finding the severity in the message registry ERROR={ERROR}",
                        "ERROR", entry.name);

                    // Have to choose something, just use informational.
                    _eventSeverity = 0;
                }
            }
        }

        // Convert Critical error (0x50) to Critical Error-System Termination
        // (0x51), if the AdditionalData is set to SYSTEM_TERM
        auto sevLevel = additionalData.getValue("SEVERITY_DETAIL");
        if ((_eventSeverity & 0xF0) == 0x50)
        {
            if (sevLevel.value_or("") == "SYSTEM_TERM")
            {
                // Change to Critical Error, System Termination
                _eventSeverity = 0x51;
            }
        }

        if (entry.eventType)
        {
            _eventType = *entry.eventType;
        }
        else
        {
            // There are different default event types for info errors
            // vs non info ones.
            auto sevType = static_cast<SeverityType>(_eventSeverity & 0xF0);
            _eventType =
                (sevType == SeverityType::nonError)
                    ? static_cast<uint8_t>(EventType::miscInformational)
                    : static_cast<uint8_t>(EventType::notApplicable);
        }

        _reserved4Byte1 = 0;

        // No uses for problem domain or vector
        _problemDomain = 0;
        _problemVector = 0;

        // These will be set in pel_rules::check() if they're still
        // at the default value.
        if (!mfgActionFlagStatus)
        {
            _actionFlags = entry.actionFlags.value_or(actionFlagsDefault);
        }

        _states = 0;

        _valid = true;
    }
}

UserHeader::UserHeader(Stream& pel)
{
    try
    {
        unflatten(pel);
        validate();
    }
    catch (const std::exception& e)
    {
        lg2::error("Cannot unflatten user header: {EXCEPTION}", "EXCEPTION", e);
        _valid = false;
    }
}

void UserHeader::validate()
{
    bool failed = false;
    if (header().id != static_cast<uint16_t>(SectionID::userHeader))
    {
        lg2::error("Invalid user header section ID: {HEADER_ID}", "HEADER_ID",
                   lg2::hex, header().id);
        failed = true;
    }

    if (header().version != userHeaderVersion)
    {
        lg2::error("Invalid user header version: {HEADER_VERSION}",
                   "HEADER_VERSION", lg2::hex, header().version);
        failed = true;
    }

    _valid = (failed) ? false : true;
}

std::optional<std::string> UserHeader::getJSON(uint8_t creatorID) const
{
    std::string severity;
    std::string subsystem;
    std::string eventScope;
    std::string eventType;
    std::vector<std::string> actionFlags;
    severity = pv::getValue(_eventSeverity, pel_values::severityValues);
    subsystem = pv::getValue(_eventSubsystem, pel_values::subsystemValues);
    eventScope = pv::getValue(_eventScope, pel_values::eventScopeValues);
    eventType = pv::getValue(_eventType, pel_values::eventTypeValues);
    actionFlags = pv::getValuesBitwise(_actionFlags,
                                       pel_values::actionFlagsValues);

    std::string hostState{"Invalid"};
    std::string hmcState{"Invalid"};
    auto iter = pv::transmissionStates.find(
        static_cast<TransmissionState>(hostTransmissionState()));
    if (iter != pv::transmissionStates.end())
    {
        hostState = iter->second;
    }
    auto iter1 = pv::transmissionStates.find(
        static_cast<TransmissionState>(hmcTransmissionState()));
    if (iter1 != pv::transmissionStates.end())
    {
        hmcState = iter1->second;
    }

    std::string uh;
    jsonInsert(uh, pv::sectionVer, getNumberString("%d", userHeaderVersion), 1);
    jsonInsert(uh, pv::subSection, getNumberString("%d", _header.subType), 1);
    jsonInsert(uh, "Log Committed by",
               getComponentName(_header.componentID, creatorID), 1);
    jsonInsert(uh, "Subsystem", subsystem, 1);
    jsonInsert(uh, "Event Scope", eventScope, 1);
    jsonInsert(uh, "Event Severity", severity, 1);
    jsonInsert(uh, "Event Type", eventType, 1);
    jsonInsertArray(uh, "Action Flags", actionFlags, 1);
    jsonInsert(uh, "Host Transmission", hostState, 1);
    jsonInsert(uh, "HMC Transmission", hmcState, 1);
    uh.erase(uh.size() - 2);
    return uh;
}

std::optional<uint8_t> UserHeader::getSeverity(
    const std::vector<message::RegistrySeverity>& severities,
    const DataInterfaceBase& dataIface) const
{
    const uint8_t* s = nullptr;
    std::vector<std::string> systemNames;

    // getSystemNames makes D-Bus calls, so only call it if we
    // know we'll need it because there is a system name in the sev list
    if (std::any_of(severities.begin(), severities.end(),
                    [](const auto& sev) { return !sev.system.empty(); }))
    {
        try
        {
            systemNames = dataIface.getSystemNames();
        }
        catch (const std::exception& e)
        {
            lg2::error(
                "Failed trying to look up system names on D-Bus ERROR={ERROR}",
                "ERROR", e);
            return std::nullopt;
        }
    }

    // Find the severity to use for this system type, or use the default
    // entry (where no system type is specified).
    for (const auto& sev : severities)
    {
        if (std::find(systemNames.begin(), systemNames.end(), sev.system) !=
            systemNames.end())
        {
            s = &sev.severity;
            break;
        }
        else if (sev.system.empty())
        {
            s = &sev.severity;
        }
    }

    if (s)
    {
        return *s;
    }

    return std::nullopt;
}

} // namespace pels
} // namespace openpower
