/**
 * Copyright © 2020 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 "device.hpp"
#include "id_map.hpp"
#include "services.hpp"

#include <memory>
#include <stdexcept>
#include <string>
#include <utility>
#include <vector>

namespace phosphor::power::regulators
{

// Forward declarations to avoid circular dependencies
class System;

/**
 * @class Chassis
 *
 * A chassis within the system.
 *
 * Chassis are large enclosures that can be independently powered off and on by
 * the BMC.  Small and mid-sized systems may contain a single chassis.  In a
 * large rack-mounted system, each drawer may correspond to a chassis.
 *
 * A C++ Chassis object only needs to be created if the physical chassis
 * contains regulators that need to be configured or monitored.
 */
class Chassis
{
  public:
    // Specify which compiler-generated methods we want
    Chassis() = delete;
    Chassis(const Chassis&) = delete;
    Chassis(Chassis&&) = delete;
    Chassis& operator=(const Chassis&) = delete;
    Chassis& operator=(Chassis&&) = delete;
    ~Chassis() = default;

    /**
     * Constructor.
     *
     * Throws an exception if any of the input parameters are invalid.
     *
     * @param number Chassis number within the system.  Chassis numbers start at
     *               1 because chassis 0 represents the entire system.
     * @param inventoryPath D-Bus inventory path for this chassis
     * @param devices Devices within this chassis, if any.  The vector should
     *                contain regulator devices and any related devices required
     *                to perform regulator operations.
     */
    explicit Chassis(unsigned int number, const std::string& inventoryPath,
                     std::vector<std::unique_ptr<Device>> devices =
                         std::vector<std::unique_ptr<Device>>{}) :
        number{number},
        inventoryPath{inventoryPath}, devices{std::move(devices)}
    {
        if (number < 1)
        {
            throw std::invalid_argument{"Invalid chassis number: " +
                                        std::to_string(number)};
        }
    }

    /**
     * Adds the Device and Rail objects in this chassis to the specified IDMap.
     *
     * @param idMap mapping from IDs to the associated Device/Rail/Rule objects
     */
    void addToIDMap(IDMap& idMap);

    /**
     * Clear any cached data about hardware devices.
     */
    void clearCache();

    /**
     * Clears all error history.
     *
     * All data on previously logged errors will be deleted.  If errors occur
     * again in the future they will be logged again.
     *
     * This method is normally called when the system is being powered on.
     */
    void clearErrorHistory();

    /**
     * Close the devices within this chassis, if any.
     *
     * @param services system services like error logging and the journal
     */
    void closeDevices(Services& services);

    /**
     * Configure the devices within this chassis, if any.
     *
     * This method should be called during the boot before regulators are
     * enabled.
     *
     * @param services system services like error logging and the journal
     * @param system system that contains this chassis
     */
    void configure(Services& services, System& system);

    /**
     * Detect redundant phase faults in regulator devices in this chassis.
     *
     * This method should be called repeatedly based on a timer.
     *
     * @param services system services like error logging and the journal
     * @param system system that contains this chassis
     */
    void detectPhaseFaults(Services& services, System& system);

    /**
     * Returns the devices within this chassis, if any.
     *
     * The vector contains regulator devices and any related devices
     * required to perform regulator operations.
     *
     * @return devices in chassis
     */
    const std::vector<std::unique_ptr<Device>>& getDevices() const
    {
        return devices;
    }

    /**
     * Returns the D-Bus inventory path for this chassis.
     *
     * @return inventory path
     */
    const std::string& getInventoryPath() const
    {
        return inventoryPath;
    }

    /**
     * Returns the chassis number within the system.
     *
     * @return chassis number
     */
    unsigned int getNumber() const
    {
        return number;
    }

    /**
     * Monitors the sensors for the voltage rails produced by this chassis, if
     * any.
     *
     * This method should be called repeatedly based on a timer.
     *
     * @param services system services like error logging and the journal
     * @param system system that contains the chassis
     */
    void monitorSensors(Services& services, System& system);

  private:
    /**
     * Chassis number within the system.
     *
     * Chassis numbers start at 1 because chassis 0 represents the entire
     * system.
     */
    const unsigned int number{};

    /**
     * D-Bus inventory path for this chassis.
     */
    const std::string inventoryPath{};

    /**
     * Devices within this chassis, if any.
     *
     * The vector contains regulator devices and any related devices
     * required to perform regulator operations.
     */
    std::vector<std::unique_ptr<Device>> devices{};
};

} // namespace phosphor::power::regulators
