#pragma once

#include <filesystem>
#include <string>
#include <vector>

namespace phosphor
{
namespace pmbus
{

namespace fs = std::filesystem;

// The file name Linux uses to capture the STATUS_WORD from pmbus.
constexpr auto STATUS_WORD = "status0";

// The file name Linux uses to capture the STATUS_INPUT from pmbus.
constexpr auto STATUS_INPUT = "status0_input";

// Voltage out status.
// Overvoltage fault or warning, Undervoltage fault or warning, maximum or
// minimum warning, ....
// Uses Page substitution
constexpr auto STATUS_VOUT = "statusP_vout";

namespace status_vout
{
// Mask of bits that are only warnings
constexpr auto WARNING_MASK = 0x6A;
} // namespace status_vout

// Current output status bits.
constexpr auto STATUS_IOUT = "status0_iout";

// Manufacturing specific status bits
constexpr auto STATUS_MFR = "status0_mfr";

// Reports on the status of any fans installed in position 1 and 2.
constexpr auto STATUS_FANS_1_2 = "status0_fans12";

// Reports on temperature faults or warnings. Overtemperature fault,
// overtemperature warning, undertemperature warning, undertemperature fault.
constexpr auto STATUS_TEMPERATURE = "status0_temp";

namespace status_word
{
constexpr auto VOUT_FAULT = 0x8000;

// The IBM CFF power supply driver does map this bit to power1_alarm in the
// hwmon space, but since the other bits that need to be checked do not have
// a similar mapping, the code will just read STATUS_WORD and use bit masking
// to see if the INPUT FAULT OR WARNING bit is on.
constexpr auto INPUT_FAULT_WARN = 0x2000;

// The bit mask representing the MFRSPECIFIC fault, bit 4 of STATUS_WORD high
// byte. A manufacturer specific fault or warning has occurred.
constexpr auto MFR_SPECIFIC_FAULT = 0x1000;

// The bit mask representing the POWER_GOOD Negated bit of the STATUS_WORD.
constexpr auto POWER_GOOD_NEGATED = 0x0800;

// The bit mask representing the FAN FAULT or WARNING bit of the STATUS_WORD.
// Bit 2 of the high byte of STATUS_WORD.
constexpr auto FAN_FAULT = 0x0400;

// The bit mask representing the UNITI_IS_OFF bit of the STATUS_WORD.
constexpr auto UNIT_IS_OFF = 0x0040;

// Bit 5 of the STATUS_BYTE, or lower byte of STATUS_WORD is used to indicate
// an output overvoltage fault.
constexpr auto VOUT_OV_FAULT = 0x0020;

// The bit mask representing that an output overcurrent fault has occurred.
constexpr auto IOUT_OC_FAULT = 0x0010;

// The IBM CFF power supply driver does map this bit to in1_alarm, however,
// since a number of the other bits are not mapped that way for STATUS_WORD,
// this code will just read the entire STATUS_WORD and use bit masking to find
// out if that fault is on.
constexpr auto VIN_UV_FAULT = 0x0008;

// The bit mask representing the TEMPERATURE FAULT or WARNING bit of the
// STATUS_WORD. Bit 2 of the low byte (STATUS_BYTE).
constexpr auto TEMPERATURE_FAULT_WARN = 0x0004;

} // namespace status_word

namespace status_vout
{
// The IBM CFF power supply driver maps MFR's OV_FAULT and VAUX_FAULT to this
// bit.
constexpr auto OV_FAULT = 0x80;

// The IBM CFF power supply driver maps MFR's UV_FAULT to this bit.
constexpr auto UV_FAULT = 0x10;
} // namespace status_vout

namespace status_temperature
{
// Overtemperature Fault
constexpr auto OT_FAULT = 0x80;
} // namespace status_temperature

constexpr auto ON_OFF_CONFIG = "on_off_config";

// From PMBus Specification Part II Revsion 1.2:
// The ON_OFF_CONFIG command configures the combination of CONTROL pin input
// and serial bus commands needed to turn the unit on and off. This includes how
// the unit responds when power is applied.
// Bits [7:5] - 000 - Reserved
// Bit 4 - 1 - Unit does not power up until commanded by the CONTROL pin and
// OPERATION command (as programmed in bits [3:0]).
// Bit 3 - 0 - Unit ignores the on/off portion of the OPERATION command from
// serial bus.
// Bit 2 - 1 - Unit requires the CONTROL pin to be asserted to start the unit.
// Bit 1 - 0 - Polarity of the CONTROL pin. Active low (Pull pin low to start
// the unit).
// Bit 0 - 1 - Turn off the output and stop transferring energy to the output as
// fast as possible.
constexpr auto ON_OFF_CONFIG_CONTROL_PIN_ONLY = 0x15;

/**
 * Where the access should be done
 */
enum class Type
{
    Base,            // base device directory
    Hwmon,           // hwmon directory
    Debug,           // pmbus debug directory
    DeviceDebug,     // device debug directory
    HwmonDeviceDebug // hwmon device debug directory
};

/**
 * @class PMBusBase
 *
 * This is a base class for PMBus to assist with unit testing via mocking.
 */
class PMBusBase
{
  public:
    virtual ~PMBusBase() = default;

    virtual uint64_t read(const std::string& name, Type type) = 0;
    virtual std::string readString(const std::string& name, Type type) = 0;
    virtual void writeBinary(const std::string& name, std::vector<uint8_t> data,
                             Type type) = 0;
};

/**
 * Wrapper function for PMBus
 *
 * @param[in] bus - I2C bus
 * @param[in] address - I2C address (as a 2-byte string, e.g. 0069)
 *
 * @return PMBusBase pointer
 */
std::unique_ptr<PMBusBase> createPMBus(std::uint8_t bus,
                                       const std::string& address);

/**
 * @class PMBus
 *
 * This class is an interface to communicating with PMBus devices
 * by reading and writing sysfs files.
 *
 * Based on the Type parameter, the accesses can either be done
 * in the base device directory (the one passed into the constructor),
 * or in the hwmon directory for the device.
 */
class PMBus : public PMBusBase
{
  public:
    PMBus() = delete;
    virtual ~PMBus() = default;
    PMBus(const PMBus&) = default;
    PMBus& operator=(const PMBus&) = default;
    PMBus(PMBus&&) = default;
    PMBus& operator=(PMBus&&) = default;

    /**
     * Constructor
     *
     * @param[in] path - path to the sysfs directory
     */
    PMBus(const std::string& path) : basePath(path)
    {
        findHwmonDir();
    }

    /**
     * Constructor
     *
     * This version is required when DeviceDebug
     * access will be used.
     *
     * @param[in] path - path to the sysfs directory
     * @param[in] driverName - the device driver name
     * @param[in] instance - chip instance number
     */
    PMBus(const std::string& path, const std::string& driverName,
          size_t instance) :
        basePath(path),
        driverName(driverName), instance(instance)
    {
        findHwmonDir();
    }

    /**
     * Wrapper function for PMBus
     *
     * @param[in] bus - I2C bus
     * @param[in] address - I2C address (as a 2-byte string, e.g. 0069)
     *
     * @return PMBusBase pointer
     */
    static std::unique_ptr<PMBusBase> createPMBus(std::uint8_t bus,
                                                  const std::string& address);

    /**
     * Reads a file in sysfs that represents a single bit,
     * therefore doing a PMBus read.
     *
     * @param[in] name - path concatenated to
     *                   basePath to read
     * @param[in] type - Path type
     *
     * @return bool - false if result was 0, else true
     */
    bool readBit(const std::string& name, Type type);

    /**
     * Reads a file in sysfs that represents a single bit,
     * where the page number passed in is substituted
     * into the name in place of the 'P' character in it.
     *
     * @param[in] name - path concatenated to
     *                   basePath to read
     * @param[in] page - page number
     * @param[in] type - Path type
     *
     * @return bool - false if result was 0, else true
     */
    bool readBitInPage(const std::string& name, size_t page, Type type);
    /**
     * Checks if the file for the given name and type exists.
     *
     * @param[in] name   - path concatenated to basePath to read
     * @param[in] type   - Path type
     *
     * @return bool - True if file exists, false if it does not.
     */
    bool exists(const std::string& name, Type type);

    /**
     * Read byte(s) from file in sysfs.
     *
     * @param[in] name   - path concatenated to basePath to read
     * @param[in] type   - Path type
     *
     * @return uint64_t - Up to 8 bytes of data read from file.
     */
    uint64_t read(const std::string& name, Type type) override;

    /**
     * Read a string from file in sysfs.
     *
     * @param[in] name   - path concatenated to basePath to read
     * @param[in] type   - Path type
     *
     * @return string - The data read from the file.
     */
    std::string readString(const std::string& name, Type type) override;

    /**
     * Read data from a binary file in sysfs.
     *
     * @param[in] name   - path concatenated to basePath to read
     * @param[in] type   - Path type
     * @param[in] length - length of data to read, in bytes
     *
     * @return vector<uint8_t> - The data read from the file.
     */
    std::vector<uint8_t> readBinary(const std::string& name, Type type,
                                    size_t length);

    /**
     * Writes an integer value to the file, therefore doing
     * a PMBus write.
     *
     * @param[in] name - path concatenated to
     *                   basePath to write
     * @param[in] value - the value to write
     * @param[in] type - Path type
     */
    void write(const std::string& name, int value, Type type);

    /**
     * Writes binary data to a file in sysfs.
     *
     * @param[in] name - path concatenated to basePath to write
     * @param[in] data - The data to write to the file
     * @param[in] type - Path type
     */
    void writeBinary(const std::string& name, std::vector<uint8_t> data,
                     Type type) override;

    /**
     * Returns the sysfs base path of this device
     */
    inline const auto& path() const
    {
        return basePath;
    }

    /**
     * Replaces the 'P' in the string passed in with
     * the page number passed in.
     *
     * For example:
     *   insertPageNum("inP_enable", 42)
     *   returns "in42_enable"
     *
     * @param[in] templateName - the name string, with a 'P' in it
     * @param[in] page - the page number to insert where the P was
     *
     * @return string - the new string with the page number in it
     */
    static std::string insertPageNum(const std::string& templateName,
                                     size_t page);

    /**
     * Finds the path relative to basePath to the hwmon directory
     * for the device and stores it in hwmonRelPath.
     */
    void findHwmonDir();

    /**
     * Returns the path to use for the passed in type.
     *
     * @param[in] type - Path type
     *
     * @return fs::path - the full path
     */
    fs::path getPath(Type type);

  private:
    /**
     * Returns the device name
     *
     * This is found in the 'name' file in basePath.
     *
     * @return string - the device name
     */
    std::string getDeviceName();

    /**
     * The sysfs device path
     */
    fs::path basePath;

    /**
     * The directory name under the basePath hwmon directory
     */
    fs::path hwmonDir;

    /**
     * The device driver name.  Used for finding the device
     * debug directory.  Not required if that directory
     * isn't used.
     */
    std::string driverName;

    /**
     * The device instance number.
     *
     * Used in conjunction with the driver name for finding
     * the debug directory.  Not required if that directory
     * isn't used.
     */
    size_t instance = 0;

    /**
     * The pmbus debug path with status files
     */
    const fs::path debugPath = "/sys/kernel/debug/";
};

} // namespace pmbus
} // namespace phosphor
