/**
 * Copyright © 2024 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.
 */
#pragma once

#include "pmbus.hpp"
#include "xyz/openbmc_project/Logging/Entry/server.hpp"

#include <phosphor-logging/lg2.hpp>
#include <sdbusplus/bus.hpp>
#include <sdbusplus/exception.hpp>

#include <cstdint>
#include <format>
#include <map>
#include <memory>
#include <string>
#include <vector>

namespace phosphor::power::sequencer
{

using namespace sdbusplus::xyz::openbmc_project::Logging::server;
using PMBusBase = phosphor::pmbus::PMBusBase;
using PMBus = phosphor::pmbus::PMBus;

/**
 * @class Services
 *
 * Abstract base class that provides an interface to system services like error
 * logging and the journal.
 */
class Services
{
  public:
    // Specify which compiler-generated methods we want
    Services() = default;
    Services(const Services&) = delete;
    Services(Services&&) = delete;
    Services& operator=(const Services&) = delete;
    Services& operator=(Services&&) = delete;
    virtual ~Services() = default;

    /**
     * Returns the D-Bus bus object.
     *
     * @return D-Bus bus
     */
    virtual sdbusplus::bus_t& getBus() = 0;

    /**
     * Logs an error message in the system journal.
     *
     * @param message message to log
     */
    virtual void logErrorMsg(const std::string& message) = 0;

    /**
     * Logs an informational message in the system journal.
     *
     * @param message message to log
     */
    virtual void logInfoMsg(const std::string& message) = 0;

    /**
     * Logs an error.
     *
     * If logging fails, a message is written to the system journal but an
     * exception is not thrown.
     *
     * @param message Message property of the error log entry
     * @param severity Severity property of the error log entry
     * @param additionalData AdditionalData property of the error log entry
     */
    virtual void
        logError(const std::string& message, Entry::Level severity,
                 std::map<std::string, std::string>& additionalData) = 0;

    /**
     * Returns whether the hardware with the specified inventory path is
     * present.
     *
     * Throws an exception if an error occurs while obtaining the presence
     * value.
     *
     * @param inventoryPath D-Bus inventory path of the hardware
     * @return true if hardware is present, false otherwise
     */
    virtual bool isPresent(const std::string& inventoryPath) = 0;

    /**
     * Reads all the GPIO values on the chip with the specified label.
     *
     * Throws an exception if an error occurs while obtaining the values.
     *
     * @param chipLabel label identifying the chip with the GPIOs
     * @return GPIO values
     */
    virtual std::vector<int> getGPIOValues(const std::string& chipLabel) = 0;

    /**
     * Creates object for communicating with a PMBus device by reading and
     * writing sysfs files.
     *
     * Throws an exception if an error occurs.
     *
     * @param bus I2C bus
     * @param address I2C address
     * @param driverName Device driver name
     * @param instance Chip instance number
     * @return object for communicating with PMBus device
     */
    virtual std::unique_ptr<PMBusBase>
        createPMBus(uint8_t bus, uint16_t address,
                    const std::string& driverName = "",
                    size_t instance = 0) = 0;

    /**
     * Creates a BMC dump.
     */
    virtual void createBMCDump() = 0;

    /**
     * Clear any cached data.
     *
     * Some data may be cached for performance reasons, such as hardware
     * presence.  Clearing the cache results in the latest data being obtained
     * by a subsequent method calls.
     */
    virtual void clearCache() = 0;
};

/**
 * @class BMCServices
 *
 * Implementation of the Services interface using standard BMC system services.
 */
class BMCServices : public Services
{
  public:
    // Specify which compiler-generated methods we want
    BMCServices() = delete;
    BMCServices(const BMCServices&) = delete;
    BMCServices(BMCServices&&) = delete;
    BMCServices& operator=(const BMCServices&) = delete;
    BMCServices& operator=(BMCServices&&) = delete;
    virtual ~BMCServices() = default;

    /**
     * Constructor.
     *
     * @param bus D-Bus bus object
     */
    explicit BMCServices(sdbusplus::bus_t& bus) : bus{bus} {}

    /** @copydoc Services::getBus() */
    virtual sdbusplus::bus_t& getBus() override
    {
        return bus;
    }

    /** @copydoc Services::logErrorMsg() */
    virtual void logErrorMsg(const std::string& message) override
    {
        lg2::error(message.c_str());
    }

    /** @copydoc Services::logInfoMsg() */
    virtual void logInfoMsg(const std::string& message) override
    {
        lg2::info(message.c_str());
    }

    /** @copydoc Services::logError() */
    virtual void
        logError(const std::string& message, Entry::Level severity,
                 std::map<std::string, std::string>& additionalData) override;

    /** @copydoc Services::isPresent() */
    virtual bool isPresent(const std::string& inventoryPath) override;

    /** @copydoc Services::getGPIOValues() */
    virtual std::vector<int>
        getGPIOValues(const std::string& chipLabel) override;

    /** @copydoc Services::createPMBus() */
    virtual std::unique_ptr<PMBusBase>
        createPMBus(uint8_t bus, uint16_t address,
                    const std::string& driverName = "",
                    size_t instance = 0) override
    {
        std::string path = std::format("/sys/bus/i2c/devices/{}-{:04x}", bus,
                                       address);
        return std::make_unique<PMBus>(path, driverName, instance);
    }

    /** @copydoc Services::createBMCDump() */
    virtual void createBMCDump() override;

    /** @copydoc Services::clearCache() */
    virtual void clearCache() override
    {
        presenceCache.clear();
    }

  private:
    /**
     * Returns whether the specified D-Bus exception is one of the expected
     * types that can be thrown if hardware is not present.
     *
     * @return true if exception type is expected, false otherwise
     */
    bool isExpectedException(const sdbusplus::exception_t& e);

    /**
     * D-Bus bus object.
     */
    sdbusplus::bus_t& bus;

    /**
     * Cached presence data.
     *
     * Map from inventory paths to presence values.
     */
    std::map<std::string, bool> presenceCache{};
};

} // namespace phosphor::power::sequencer
