#pragma once

#include "device.hpp"
#include "gpio.hpp"
#include "pmbus.hpp"
#include "types.hpp"

#include <sdbusplus/bus.hpp>

#include <algorithm>
#include <filesystem>
#include <map>
#include <vector>

namespace phosphor
{
namespace power
{

// Error type, callout
using PartCallout = std::tuple<ucd90160::extraAnalysisType, std::string>;

/**
 * @class UCD90160
 *
 * This class implements fault analysis for the UCD90160
 * power sequencer device.
 *
 */
class UCD90160 : public Device
{
  public:
    UCD90160() = delete;
    ~UCD90160() = default;
    UCD90160(const UCD90160&) = delete;
    UCD90160& operator=(const UCD90160&) = delete;
    UCD90160(UCD90160&&) = default;
    UCD90160& operator=(UCD90160&&) = default;

    /**
     * Constructor
     *
     * @param[in] instance - the device instance number
     * @param[in] bus - D-Bus bus object
     */
    UCD90160(size_t instance, sdbusplus::bus::bus& bus);

    /**
     * Analyzes the device for errors when the device is
     * known to be in an error state.  A log will be created.
     */
    void onFailure() override;

    /**
     * Checks the device for errors and only creates a log
     * if one is found.
     */
    void analyze() override;

    /**
     * Clears faults in the device
     */
    void clearFaults() override
    {
    }

  private:
    /**
     * Reports an error for a GPU PGOOD failure
     *
     * @param[in] callout - the GPU callout string
     */
    void gpuPGOODError(const std::string& callout);

    /**
     * Reports an error for a GPU OverTemp failure
     *
     * @param[in] callout - the GPU callout string
     */
    void gpuOverTempError(const std::string& callout);

    /**
     * Reports an error for a MEM_GOODx failure.
     *
     * @param[in] callout - The MEM callout string
     */
    void memGoodError(const std::string& callout);

    /**
     * Given the device path for a chip, find its gpiochip
     * path
     *
     * @param[in] path - device path, like
     *                   /sys/devices/.../i2c-11/11-0064
     *
     * @return fs::path - The gpiochip path, like
     *                   /dev/gpiochip1
     */
    static std::filesystem::path
        findGPIODevice(const std::filesystem::path& path);

    /**
     * Checks for VOUT faults on the device.
     *
     * This device can monitor voltages of its dependent
     * devices, and VOUT faults are voltage faults
     * on these devices.
     *
     * @return bool - true if an error log was created
     */
    bool checkVOUTFaults();

    /**
     * Checks for PGOOD faults on the device.
     *
     * This device can monitor the PGOOD signals of its dependent
     * devices, and this check will look for faults of
     * those PGOODs.
     *
     * @param[in] polling - If this is running while polling for errors,
     *                      as opposing to analyzing a fail condition.
     *
     * @return bool - true if an error log was created
     */
    bool checkPGOODFaults(bool polling);

    /**
     * Creates an error log when the device has an error
     * but it isn't a PGOOD or voltage failure.
     */
    void createPowerFaultLog();

    /**
     * Reads the status_word register
     *
     * @return uint16_t - the register contents
     */
    uint16_t readStatusWord();

    /**
     * Reads the mfr_status register
     *
     * @return uint32_t - the register contents
     */
    uint32_t readMFRStatus();

    /**
     * Does any additional fault analysis based on the
     * value of the extraAnalysisType field in the GPIOConfig
     * entry.
     *
     * Used to get better callouts.
     *
     * @param[in] config - the GPIOConfig entry to use
     *
     * @return bool - true if a HW error was found, false else
     */
    bool doExtraAnalysis(const ucd90160::GPIConfig& config);

    /**
     * Does additional fault analysis using GPIOs to
     * specifically identify the failing part.
     *
     * Used when there are too many PGOOD inputs for
     * the UCD90160 to handle, so just a summary bit
     * is wired into the chip, and then the specific
     * fault GPIOs are off of a different GPIO device,
     * like an IO expander.
     *
     * @param[in] type - the type of analysis to do
     *
     * @return bool - true if a HW error was found, false else
     */
    bool doGPIOAnalysis(ucd90160::extraAnalysisType type);

    /**
     * Says if we've already logged a Vout fault
     *
     * The policy is only 1 of the same error will
     * be logged for the duration of a class instance.
     *
     * @param[in] page - the page to check
     *
     * @return bool - if we've already logged a fault against
     *                this page
     */
    inline bool isVoutFaultLogged(uint32_t page) const
    {
        return std::find(voutErrors.begin(), voutErrors.end(), page) !=
               voutErrors.end();
    }

    /**
     * Saves that a Vout fault has been logged
     *
     * @param[in] page - the page the error was logged against
     */
    inline void setVoutFaultLogged(uint32_t page)
    {
        voutErrors.push_back(page);
    }

    /**
     * Says if we've already logged a PGOOD fault
     *
     * The policy is only 1 of the same errors will
     * be logged for the duration of a class instance.
     *
     * @param[in] input - the input to check
     *
     * @return bool - if we've already logged a fault against
     *                this input
     */
    inline bool isPGOODFaultLogged(uint32_t input) const
    {
        return std::find(pgoodErrors.begin(), pgoodErrors.end(), input) !=
               pgoodErrors.end();
    }

    /**
     * Says if we've already logged a specific fault
     * against a specific part
     *
     * @param[in] callout - error type and name tuple
     *
     * @return bool - if we've already logged this fault
     *                against this part
     */
    inline bool isPartCalledOut(const PartCallout& callout) const
    {
        return std::find(callouts.begin(), callouts.end(), callout) !=
               callouts.end();
    }

    /**
     * Saves that a PGOOD fault has been logged
     *
     * @param[in] input - the input the error was logged against
     */
    inline void setPGOODFaultLogged(uint32_t input)
    {
        pgoodErrors.push_back(input);
    }

    /**
     * Saves that a specific fault on a specific part has been done
     *
     * @param[in] callout - error type and name tuple
     */
    inline void setPartCallout(const PartCallout& callout)
    {
        callouts.push_back(callout);
    }

    /**
     * List of pages that Vout errors have
     * already been logged against
     */
    std::vector<uint32_t> voutErrors;

    /**
     * List of inputs that PGOOD errors have
     * already been logged against
     */
    std::vector<uint32_t> pgoodErrors;

    /**
     * List of callouts that already been done
     */
    std::vector<PartCallout> callouts;

    /**
     * The read/write interface to this hardware
     */
    pmbus::PMBus interface;

    /**
     * A map of GPI pin IDs to the GPIO object
     * used to access them
     */
    std::map<size_t, std::unique_ptr<gpio::GPIO>> gpios;

    /**
     * Keeps track of device access errors to avoid repeatedly
     * logging errors for bad hardware
     */
    bool accessError = false;

    /**
     * Keeps track of GPIO access errors when doing the in depth
     * PGOOD fault analysis to avoid repeatedly logging errors
     * for bad hardware
     */
    bool gpioAccessError = false;

    /**
     * The path to the GPIO device used to read
     * the GPI (PGOOD) status
     */
    std::filesystem::path gpioDevice;

    /**
     * The D-Bus bus object
     */
    sdbusplus::bus::bus& bus;

    /**
     * Map of device instance to the instance specific data
     */
    static const ucd90160::DeviceMap deviceMap;
};

} // namespace power
} // namespace phosphor
