/**
 * Copyright © 2021 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 "error_logging_utils.hpp"

#include "config_file_parser_error.hpp"
#include "exception_utils.hpp"
#include "i2c_interface.hpp"
#include "journal.hpp"
#include "pmbus_error.hpp"
#include "write_verification_error.hpp"

#include <sdbusplus/exception.hpp>

#include <vector>

namespace phosphor::power::regulators::error_logging_utils
{

void logError(std::exception_ptr eptr, Entry::Level severity,
              Services& services)
{
    // Specify empty error history so that all error types will be logged
    ErrorHistory history{};
    logError(eptr, severity, services, history);
}

void logError(std::exception_ptr eptr, Entry::Level severity,
              Services& services, ErrorHistory& history)
{
    // Check for null exception pointer
    if (!eptr)
    {
        return;
    }

    // Get exception to log from specified exception and any nested exceptions
    std::exception_ptr exceptionToLog = internal::getExceptionToLog(eptr);

    // Log an error based on the exception
    ErrorLogging& errorLogging = services.getErrorLogging();
    Journal& journal = services.getJournal();
    ErrorType errorType{};
    try
    {
        std::rethrow_exception(exceptionToLog);
    }
    catch (const ConfigFileParserError& e)
    {
        errorType = ErrorType::configFile;
        if (!history.wasLogged(errorType))
        {
            history.setWasLogged(errorType, true);
            errorLogging.logConfigFileError(severity, journal);
        }
    }
    catch (const PMBusError& e)
    {
        errorType = ErrorType::pmbus;
        if (!history.wasLogged(errorType))
        {
            history.setWasLogged(errorType, true);
            errorLogging.logPMBusError(severity, journal, e.getInventoryPath());
        }
    }
    catch (const WriteVerificationError& e)
    {
        errorType = ErrorType::writeVerification;
        if (!history.wasLogged(errorType))
        {
            history.setWasLogged(errorType, true);
            errorLogging.logWriteVerificationError(severity, journal,
                                                   e.getInventoryPath());
        }
    }
    catch (const i2c::I2CException& e)
    {
        errorType = ErrorType::i2c;
        if (!history.wasLogged(errorType))
        {
            history.setWasLogged(errorType, true);
            errorLogging.logI2CError(severity, journal, e.bus, e.addr,
                                     e.errorCode);
        }
    }
    catch (const sdbusplus::exception_t& e)
    {
        errorType = ErrorType::dbus;
        if (!history.wasLogged(errorType))
        {
            history.setWasLogged(errorType, true);
            errorLogging.logDBusError(severity, journal);
        }
    }
    catch (const std::exception& e)
    {
        errorType = ErrorType::internal;
        if (!history.wasLogged(errorType))
        {
            history.setWasLogged(errorType, true);
            errorLogging.logInternalError(severity, journal);
        }
    }
    catch (...)
    {
        errorType = ErrorType::internal;
        if (!history.wasLogged(errorType))
        {
            history.setWasLogged(errorType, true);
            errorLogging.logInternalError(severity, journal);
        }
    }
}

namespace internal
{

std::exception_ptr getExceptionToLog(std::exception_ptr eptr)
{
    // Default to selecting the outermost exception
    std::exception_ptr exceptionToLog{eptr};

    // Get vector containing this exception and any nested exceptions
    std::vector<std::exception_ptr> exceptions =
        exception_utils::getExceptions(eptr);

    // Define temporary constants for exception priorities
    const int lowPriority{0}, mediumPriority{1}, highPriority{2};

    // Loop through the exceptions from innermost to outermost.  Find the
    // exception with the highest priority.  If there is a tie, select the
    // outermost exception with that priority.
    int highestPriorityFound{-1};
    for (std::exception_ptr curptr : exceptions)
    {
        int priority{-1};
        try
        {
            std::rethrow_exception(curptr);
        }
        catch (const ConfigFileParserError& e)
        {
            priority = highPriority;
        }
        catch (const PMBusError& e)
        {
            priority = highPriority;
        }
        catch (const WriteVerificationError& e)
        {
            priority = highPriority;
        }
        catch (const i2c::I2CException& e)
        {
            priority = highPriority;
        }
        catch (const sdbusplus::exception_t& e)
        {
            priority = mediumPriority;
        }
        catch (const std::exception& e)
        {
            priority = lowPriority;
        }
        catch (...)
        {
            priority = lowPriority;
        }

        if (priority >= highestPriorityFound)
        {
            highestPriorityFound = priority;
            exceptionToLog = curptr;
        }
    }

    return exceptionToLog;
}

} // namespace internal

} // namespace phosphor::power::regulators::error_logging_utils
