#pragma once

#include <fstream>
#include <experimental/filesystem>
#include "occ_bus.hpp"
#include "occ_events.hpp"
#include "occ_errors.hpp"
#include "occ_presence.hpp"
#include "config.h"

namespace open_power
{
namespace occ
{

class Manager;
class Status;
namespace fs = std::experimental::filesystem;

/** @class Device
 *  @brief Binds and unbinds the OCC driver upon request
 */
class Device
{
    public:
        Device() = delete;
        ~Device() = default;
        Device(const Device&) = delete;
        Device& operator=(const Device&) = delete;
        Device(Device&&) = default;
        Device& operator=(Device&&) = default;

        /** @brief Constructs the Device object
         *
         *  @param[in] event    - Unique ptr reference to sd_event
         *  @param[in] name     - OCC instance name
         *  @param[in] manager  - OCC manager instance
         *  @param[in] status   - OCC status instance
         *  @param[in] instance - OCC device index
         *  @param[in] callback - Optional callback on errors
         */
        Device(EventPtr& event,
               const std::string& name,
               const Manager& manager,
               Status& status,
               int instance,
               std::function<void(bool)> callBack = nullptr) :
            config(name),
            errorFile(fs::path(config) / "occ_error"),
            statusObject(status),
            busObject(instance),
            error(event, errorFile, callBack),
            presence(event,
                     fs::path(config) / "occs_present",
                     manager,
                     callBack),
            throttleProcTemp(
                event,
                fs::path(config) / "occ_dvfs_ot",
                std::bind(std::mem_fn(&Device::throttleProcTempCallback),
                          this,
                          std::placeholders::_1)),
            throttleProcPower(
                event,
                fs::path(config) / "occ_dvfs_power",
                std::bind(std::mem_fn(&Device::throttleProcPowerCallback),
                          this,
                          std::placeholders::_1)),
            throttleMemTemp(
                event,
                fs::path(config) / "occ_mem_throttle",
                std::bind(std::mem_fn(&Device::throttleMemTempCallback),
                          this,
                          std::placeholders::_1))
        {
            // Nothing to do here
        }

        /** @brief Binds device to the OCC driver */
        inline void bind()
        {
            // Reset this OCC's bus driver
            busObject.reset();

            // Bind the device
            return write(bindPath, config);
        }

        /** @brief Un-binds device from the OCC driver */
        inline void unBind()
        {
           // Unbind the device
           return write(unBindPath, config);
        }

        /** @brief Returns if device is already bound.
         *
         *  On device bind, a soft link by the name $config
         *  gets created in OCC_HWMON_PATH and gets removed
         *  on unbind
         *
         *  @return true if bound, else false
         */
        inline bool bound() const
        {
            return fs::exists(OCC_HWMON_PATH + config);
        }

        /** @brief Starts to monitor for errors */
        inline void addErrorWatch()
        {
            throttleProcTemp.addWatch();
            throttleProcPower.addWatch();
            throttleMemTemp.addWatch();
            error.addWatch();
        }

        /** @brief stops monitoring for errors */
        inline void removeErrorWatch()
        {
            // we can always safely remove watch even if we don't add it
            presence.removeWatch();
            error.removeWatch();
            error.removeWatch();
            throttleMemTemp.removeWatch();
            throttleProcPower.removeWatch();
            throttleProcTemp.removeWatch();
        }

        /** @brief Starts to watch how many OCCs are present on the master */
        inline void addPresenceWatchMaster()
        {
            if (master())
            {
                presence.addWatch();
            }
        }

        /** @brief file writer to achieve bind and unbind
         *
         *  @param[in] filename - Name of file to be written
         *  @param[in] data     - Data to be written to
         *  @return             - None
         */
        static void write(const fs::path& fileName, const std::string& data)
        {
            // If there is an error, move the exception all the way up
            std::ofstream file(fileName, std::ios::out);
            file << data;
            file.close();
            return;
        }

    private:
        /** @brief Config value to be used to do bind and unbind */
        const std::string config;

        /** @brief This file contains 0 for success, non-zero for errors */
        const fs::path errorFile;

        /**  @brief To bind the device to the OCC driver, do:
         *
         *    Write occ<#>-dev0 to: /sys/bus/platform/drivers/occ-hwmon/bind
         */
        static fs::path bindPath;

        /**  @brief To un-bind the device from the OCC driver, do:
         *    Write occ<#>-dev0 to: /sys/bus/platform/drivers/occ-hwmon/unbind
         */
        static fs::path unBindPath;

        /**  Store the associated Status instance */
        Status& statusObject;

        /**  Store the associated Bus instance */
        const Bus busObject;

        /** Abstraction of error monitoring */
        Error error;

        /** Abstraction of OCC presence monitoring */
        Presence presence;

        /** Error instances for watching for throttling events */
        Error throttleProcTemp;
        Error throttleProcPower;
        Error throttleMemTemp;

        /** @brief Returns if device represents the master OCC */
        bool master() const;

        /** @brief callback for the proc temp throttle event
         *
         *  @param[in] error - True if an error is reported, false otherwise
         */
        void throttleProcTempCallback(bool error);

        /** @brief callback for the proc power throttle event
         *
         *  @param[in] error - True if an error is reported, false otherwise
         */
        void throttleProcPowerCallback(bool error);

        /** @brief callback for the proc temp throttle event
         *
         *  @param[in] error - True if an error is reported, false otherwise
         */
        void throttleMemTempCallback(bool error);
};

} // namespace occ
} // namespace open_power
