/**
 * Copyright © 2022 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 "action.hpp"
#include "event.hpp"
#include "group.hpp"
#include "json_config.hpp"
#include "power_state.hpp"
#include "profile.hpp"
#include "sdbusplus.hpp"
#include "utils/flight_recorder.hpp"
#include "zone.hpp"

#include <nlohmann/json.hpp>
#include <phosphor-logging/lg2.hpp>
#include <sdbusplus/bus.hpp>
#include <sdbusplus/server/manager.hpp>
#include <sdeventplus/event.hpp>
#include <sdeventplus/source/event.hpp>
#include <sdeventplus/utility/timer.hpp>

#include <chrono>
#include <format>
#include <map>
#include <memory>
#include <optional>
#include <tuple>
#include <utility>
#include <vector>

namespace phosphor::fan::control::json
{

using json = nlohmann::json;

/* Application name to be appended to the path for loading a JSON config file */
constexpr auto confAppName = "control";

/* Type of timers supported */
enum class TimerType
{
    oneshot,
    repeating,
};

/**
 * Package of data required when a timer expires
 * Tuple constructed of:
 *      std::string = Timer package unique identifier
 *      std::vector<std::unique_ptr<ActionBase>> = List of pointers to actions
 * that run when the timer expires
 *      const std::vector<Group> = List of groups
 *      bool = If groups should be preloaded before actions are run
 */
using TimerPkg =
    std::tuple<std::string, std::vector<std::unique_ptr<ActionBase>>&,
               const std::vector<Group>&, bool>;
/**
 * Data associated with a running timer that's used when it expires
 * Pair constructed of:
 *      TimerType = Type of timer to manage expired timer instances
 *      TimerPkg = Package of data required when the timer expires
 */
using TimerData = std::pair<TimerType, TimerPkg>;
/* Dbus event timer */
using Timer = sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>;

/* Dbus signal object */
constexpr auto Path = 0;
constexpr auto Intf = 1;
constexpr auto Prop = 2;
using SignalObject = std::tuple<std::string, std::string, std::string>;
/* Dbus signal actions */
using TriggerActions =
    std::vector<std::reference_wrapper<std::unique_ptr<ActionBase>>>;
/**
 * Signal handler function that handles parsing a signal's message for a
 * particular signal object and stores the results in the manager
 */
using SignalHandler =
    std::function<bool(sdbusplus::message_t&, const SignalObject&, Manager&)>;
/**
 * Package of data required when a signal is received
 * Tuple constructed of:
 *     SignalHandler = Signal handler function
 *     SignalObject = Dbus signal object
 *     TriggerActions = List of actions that are run when the signal is received
 */
using SignalPkg = std::tuple<SignalHandler, SignalObject, TriggerActions>;
/**
 * Data associated to a subscribed signal
 * Tuple constructed of:
 *     std::unique_ptr<std::vector<SignalPkg>> =
 *         Pointer to list of the signal's packages
 *     std::unique_ptr<sdbusplus::bus::match_t> =
 *         Pointer to match holding the subscription to a signal
 */
using SignalData = std::tuple<std::unique_ptr<std::vector<SignalPkg>>,
                              std::unique_ptr<sdbusplus::bus::match_t>>;

/**
 * Package of data from a D-Bus call to get managed objects
 * Tuple constructed of:
 *     std::map<Path,            // D-Bus Path
 *       std::map<Intf,          // D-Bus Interface
 *         std::map<Property,    // D-Bus Property
 *         std::variant>>>       // Variant value of that property
 */
using Path_v = sdbusplus::message::object_path;
using Intf_v = std::string;
using Prop_v = std::string;
using ManagedObjects =
    std::map<Path_v, std::map<Intf_v, std::map<Prop_v, PropertyVariantType>>>;

/**
 * Actions to run when a parameter trigger runs.
 */
using ParamTriggerData = std::vector<
    std::reference_wrapper<const std::vector<std::unique_ptr<ActionBase>>>>;

/**
 * @class Manager - Represents the fan control manager's configuration
 *
 * A fan control manager configuration is optional, therefore the "manager.json"
 * file is also optional. The manager configuration is used to populate
 * fan control's manager parameters which are used in how the application
 * operates, not in how the fans are controlled.
 *
 * When no manager configuration exists, the fan control application starts,
 * processes any configured events and then begins controlling fans according
 * to those events.
 */
class Manager
{
  public:
    Manager() = delete;
    Manager(const Manager&) = delete;
    Manager(Manager&&) = delete;
    Manager& operator=(const Manager&) = delete;
    Manager& operator=(Manager&&) = delete;
    ~Manager() = default;

    /**
     * Constructor
     * Parses and populates the fan control manager attributes from a json file
     *
     * @param[in] event - sdeventplus event loop
     */
    explicit Manager(const sdeventplus::Event& event);

    /**
     * @brief Callback function to handle receiving a HUP signal to reload the
     * JSON configurations.
     */
    void sighupHandler(sdeventplus::source::Signal&,
                       const struct signalfd_siginfo*);

    /**
     * @brief Callback function to handle receiving a USR1 signal to dump
     * the flight recorder.
     */
    void dumpDebugData(sdeventplus::source::Signal&,
                       const struct signalfd_siginfo*);

    /**
     * @brief Get the active profiles of the system where an empty list
     * represents that only configuration entries without a profile defined will
     * be loaded.
     *
     * @return - The list of active profiles
     */
    static const std::vector<std::string>& getActiveProfiles();

    /**
     * @brief Load the configuration of a given JSON class object based on the
     * active profiles
     *
     * @param[in] isOptional - JSON configuration file is optional or not
     * @param[in] args - Arguments to be forwarded to each instance of `T`
     *   (*Note that a sdbusplus bus object is required as the first argument)
     *
     * @return Map of configuration entries
     *     Map of configuration keys to their corresponding configuration object
     */
    template <typename T, typename... Args>
    static std::map<configKey, std::unique_ptr<T>> getConfig(bool isOptional,
                                                             Args&&... args)
    {
        std::map<configKey, std::unique_ptr<T>> config;

        auto confFile = fan::JsonConfig::getConfFile(
            confAppName, T::confFileName, isOptional);

        if (!confFile.empty())
        {
            FlightRecorder::instance().log(
                "main", std::format("Loading configuration from {}",
                                    confFile.string()));
            for (const auto& entry : fan::JsonConfig::load(confFile))
            {
                if (entry.contains("profiles"))
                {
                    std::vector<std::string> profiles;
                    for (const auto& profile : entry["profiles"])
                    {
                        profiles.emplace_back(
                            profile.template get<std::string>());
                    }
                    // Do not create the object if its profiles are not in the
                    // list of active profiles
                    if (!profiles.empty() &&
                        !std::any_of(profiles.begin(), profiles.end(),
                                     [](const auto& name) {
                                         return std::find(
                                                    getActiveProfiles().begin(),
                                                    getActiveProfiles().end(),
                                                    name) !=
                                                getActiveProfiles().end();
                                     }))
                    {
                        continue;
                    }
                }
                auto obj =
                    std::make_unique<T>(entry, std::forward<Args>(args)...);
                config.emplace(
                    std::make_pair(obj->getName(), obj->getProfiles()),
                    std::move(obj));
            }
            lg2::info("Configuration({CONF_FILE}) loaded successfully",
                      "CONF_FILE", T::confFileName);
            FlightRecorder::instance().log(
                "main", std::format("Configuration({}) loaded successfully",
                                    T::confFileName));
        }
        return config;
    }

    /**
     * @brief Check if the given input configuration key matches with another
     * configuration key that it's to be included in
     *
     * @param[in] input - Config key to be included in another config object
     * @param[in] comp - Config key of the config object to compare with
     *
     * @return Whether the configuration object should be included
     */
    static bool inConfig(const configKey& input, const configKey& comp);

    /**
     * @brief Check if the given path and inteface is owned by a dbus service
     *
     * @param[in] path - Dbus object path
     * @param[in] intf - Dbus object interface
     *
     * @return - Whether the service has an owner for the given object path and
     * interface
     */
    static bool hasOwner(const std::string& path, const std::string& intf);

    /**
     * @brief Sets the dbus service owner state for all entries in the _servTree
     * cache and removes associated objects from the _objects cache
     *
     * @param[in] serv - Dbus service name
     * @param[in] hasOwner - Dbus service owner state
     */
    void setOwner(const std::string& serv, bool hasOwner);

    /**
     * @brief Sets the dbus service owner state of a given object
     *
     * @param[in] path - Dbus object path
     * @param[in] serv - Dbus service name
     * @param[in] intf - Dbus object interface
     * @param[in] isOwned - Dbus service owner state
     */
    void setOwner(const std::string& path, const std::string& serv,
                  const std::string& intf, bool isOwned);

    /**
     * @brief Add a set of services for a path and interface by retrieving all
     * the path subtrees to the given depth from root for the interface
     *
     * @param[in] intf - Interface to add services for
     * @param[in] depth - Depth of tree traversal from root path
     *
     * @throws - DBusMethodError
     * Throws a DBusMethodError when the `getSubTree` method call fails
     */
    static void addServices(const std::string& intf, int32_t depth);

    /**
     * @brief Get the service for a given path and interface from cached
     * dataset and attempt to add all the services for the given path/interface
     * when it's not found
     *
     * @param[in] path - Path to get service for
     * @param[in] intf - Interface to get service for
     *
     * @return - The now cached service name
     *
     * @throws - DBusMethodError
     * Ripples up a DBusMethodError exception from calling addServices
     */
    static const std::string& getService(const std::string& path,
                                         const std::string& intf);

    /**
     * @brief Get all the object paths for a given service and interface from
     * the cached dataset and try to add all the services for the given
     * interface when no paths are found and then attempt to get all the object
     * paths again
     *
     * @param[in] serv - Service name to get paths for
     * @param[in] intf - Interface to get paths for
     *
     * @return The cached object paths
     */
    std::vector<std::string> getPaths(const std::string& serv,
                                      const std::string& intf);

    /**
     * @brief Add objects to the cached dataset by first using
     * `getManagedObjects` for the same service providing the given path and
     * interface or just add the single object of the given path, interface, and
     * property if that fails.
     *
     * @param[in] path - Dbus object's path
     * @param[in] intf - Dbus object's interface
     * @param[in] prop - Dbus object's property
     *
     * @throws - DBusMethodError
     * Throws a DBusMethodError when the the service is failed to be found or
     * when the `getManagedObjects` method call fails
     */
    void addObjects(const std::string& path, const std::string& intf,
                    const std::string& prop)
    {
        addObjects(path, intf, prop, std::string{});
    }

    /**
     * @copydoc Manager::addObjects()
     *
     * If the service is known, then it can be used to add all objects
     * in that service with the interface passed in to the cache instead of
     * having to look it up.  This is done so objects can still be
     * added even when the D-Bus path passed in doesn't exist so it
     * can't be used to get a service name.
     *
     * @param[in] path - Dbus object's path
     * @param[in] intf - Dbus object's interface
     * @param[in] prop - Dbus object's property
     * @param[in] serviceName - The service of the path/intf/prop if known
     */
    void addObjects(const std::string& path, const std::string& intf,
                    const std::string& prop, const std::string& serviceName);

    /**
     * @brief Get an object's property value
     *
     * @param[in] path - Dbus object's path
     * @param[in] intf - Dbus object's interface
     * @param[in] prop - Dbus object's property
     */
    const std::optional<PropertyVariantType> getProperty(
        const std::string& path, const std::string& intf,
        const std::string& prop);

    /**
     * @brief Set/update an object's property value
     *
     * @param[in] path - Dbus object's path
     * @param[in] intf - Dbus object's interface
     * @param[in] prop - Dbus object's property
     * @param[in] value - Dbus object's property value
     */
    void setProperty(const std::string& path, const std::string& intf,
                     const std::string& prop, PropertyVariantType value);

    /**
     * @brief Remove an object's interface
     *
     * @param[in] path - Dbus object's path
     * @param[in] intf - Dbus object's interface
     */
    inline void removeInterface(const std::string& path,
                                const std::string& intf)
    {
        auto itPath = _objects.find(path);
        if (itPath != std::end(_objects))
        {
            _objects[path].erase(intf);
        }
    }

    /**
     * @brief Get the object's property value as a variant
     *
     * @param[in] path - Path of the object containing the property
     * @param[in] intf - Interface name containing the property
     * @param[in] prop - Name of property
     *
     * @return - The object's property value as a variant
     */
    static inline auto getObjValueVariant(const std::string& path,
                                          const std::string& intf,
                                          const std::string& prop)
    {
        return _objects.at(path).at(intf).at(prop);
    };

    /**
     * @brief Add a dbus timer
     *
     * @param[in] type - Type of timer
     * @param[in] interval - Timer interval in microseconds
     * @param[in] pkg - Packaged data for when timer expires
     */
    void addTimer(const TimerType type,
                  const std::chrono::microseconds interval,
                  std::unique_ptr<TimerPkg> pkg);

    /**
     * @brief Callback when a timer expires
     *
     * @param[in] data - Data to be used when the timer expired
     */
    void timerExpired(TimerData& data);

    /**
     * @brief Get the signal data for a given match string
     *
     * @param[in] sigMatch - Signal match string
     *
     * @return - Reference to the signal data for the given match string
     */
    std::vector<SignalData>& getSignal(const std::string& sigMatch)
    {
        return _signals[sigMatch];
    }

    /**
     * @brief Handle receiving signals
     *
     * @param[in] msg - Signal message containing the signal's data
     * @param[in] pkgs - Signal packages associated to the signal being handled
     */
    void handleSignal(sdbusplus::message_t& msg,
                      const std::vector<SignalPkg>* pkgs);

    /**
     * @brief Get the sdbusplus bus object
     */
    inline auto& getBus()
    {
        return _bus;
    }

    /**
     * @brief Is the power state on
     *
     * @return Current power state of the system
     */
    inline bool isPowerOn() const
    {
        return _powerState->isPowerOn();
    }

    /**
     * @brief Load all the fan control JSON configuration files
     *
     * This is where all the fan control JSON configuration files are parsed and
     * loaded into their associated objects. Anything that needs to be done when
     * the Manager object is constructed or handling a SIGHUP to reload the
     * configurations needs to be done here.
     */
    void load();

    /**
     * @brief Sets a value in the parameter map.
     *
     * If it's a std::nullopt, it will be deleted instead.
     *
     * @param[in] name - The parameter name
     * @param[in] value - The parameter value
     */
    static void setParameter(const std::string& name,
                             const std::optional<PropertyVariantType>& value)
    {
        if (value)
        {
            auto it = _parameters.find(name);
            auto changed = (it == _parameters.end()) ||
                           ((it != _parameters.end()) && it->second != *value);
            _parameters[name] = *value;

            if (changed)
            {
                runParameterActions(name);
            }
        }
        else
        {
            size_t deleted = _parameters.erase(name);

            if (deleted)
            {
                runParameterActions(name);
            }
        }
    }

    /**
     * @brief Returns a value from the parameter map
     *
     * @param[in] name - The parameter name
     *
     * @return The parameter value, or std::nullopt if not found
     */
    static std::optional<PropertyVariantType> getParameter(
        const std::string& name)
    {
        auto it = _parameters.find(name);
        if (it != _parameters.end())
        {
            return it->second;
        }

        return std::nullopt;
    }

    /**
     * @brief Runs the actions registered to a parameter
     *        trigger with this name.
     *
     * @param[in] name - The parameter name
     */
    static void runParameterActions(const std::string& name);

    /**
     * @brief Adds a parameter trigger
     *
     * @param[in] name - The parameter name
     * @param[in] actions - The actions to run on the trigger
     */
    static void addParameterTrigger(
        const std::string& name,
        std::vector<std::unique_ptr<ActionBase>>& actions);

    /* The name of the dump file */
    static const std::string dumpFile;

  private:
    /**
     * @brief Helper to detect when a property's double contains a NaN
     * (not-a-number) value.
     *
     * @param[in] value - The property to test
     */
    static bool PropertyContainsNan(const PropertyVariantType& value)
    {
        return (std::holds_alternative<double>(value) &&
                std::isnan(std::get<double>(value)));
    }

    /**
     * @brief Insert managed objects into cache, but filter out properties
     * containing unwanted NaN (not-a-number) values and properties that
     * are on D-Bus paths that aren't in an existing Group object.
     *
     * @param[in] ref - The map of ManagedObjects to insert into cache
     */
    void insertFilteredObjects(ManagedObjects& ref);

    /* The sdbusplus bus object to use */
    sdbusplus::bus_t& _bus;

    /* The sdeventplus even loop to use */
    sdeventplus::Event _event;

    /* The sdbusplus manager object to set the ObjectManager interface */
    sdbusplus::server::manager_t _mgr;

    /* Whether loading the config files is allowed or not */
    bool _loadAllowed;

    /* The system's power state determination object */
    std::unique_ptr<PowerState> _powerState;

    /* List of profiles configured */
    std::map<configKey, std::unique_ptr<Profile>> _profiles;

    /* List of active profiles */
    static std::vector<std::string> _activeProfiles;

    /* Subtree map of paths to services of interfaces(with ownership state) */
    static std::map<
        std::string,
        std::map<std::string, std::pair<bool, std::vector<std::string>>>>
        _servTree;

    /* Object map of paths to interfaces of properties and their values */
    static std::map<
        std::string,
        std::map<std::string, std::map<std::string, PropertyVariantType>>>
        _objects;

    /* List of timers and their data to be processed when expired */
    std::vector<std::pair<std::unique_ptr<TimerData>, Timer>> _timers;

    /* Map of signal match strings to a list of signal handler data */
    std::unordered_map<std::string, std::vector<SignalData>> _signals;

    /* List of zones configured */
    std::map<configKey, std::unique_ptr<Zone>> _zones;

    /* List of events configured */
    std::map<configKey, std::unique_ptr<Event>> _events;

    /**
     * @brief A map of parameter names and values that are something
     *        other than just D-Bus property values that other actions
     *        can set and use.
     */
    static std::unordered_map<std::string, PropertyVariantType> _parameters;

    /**
     * @brief Map of parameter names to the actions to run when their
     *        values change.
     */
    static std::unordered_map<std::string, TriggerActions> _parameterTriggers;

    /**
     * @brief Callback for power state changes
     *
     * @param[in] powerStateOn - Whether the power state is on or not
     *
     * Callback function bound to the PowerState object instance to handle each
     * time the power state changes.
     */
    void powerStateChanged(bool powerStateOn);

    /**
     * @brief Find the service name for a given path and interface from the
     * cached dataset
     *
     * @param[in] path - Path to get service for
     * @param[in] intf - Interface to get service for
     *
     * @return - The cached service name
     */
    static const std::string& findService(const std::string& path,
                                          const std::string& intf);

    /**
     * @brief Find all the paths for a given service and interface from the
     * cached dataset
     *
     * @param[in] serv - Service name to get paths for
     * @param[in] intf - Interface to get paths for
     *
     * @return - The cached object paths
     */
    std::vector<std::string> findPaths(const std::string& serv,
                                       const std::string& intf);

    /**
     * @brief Parse and set the configured profiles from the profiles JSON file
     *
     * Retrieves the optional profiles JSON configuration file, parses it, and
     * creates a list of configured profiles available to the other
     * configuration files. These profiles can be used to remove or include
     * entries within the other configuration files.
     */
    void setProfiles();

    /**
     * @brief Dump the _objects, _servTree, and _parameters maps to JSON
     *
     * @param[out] data - The JSON that will be filled in
     */
    void dumpCache(json& data);

    /**
     * @brief Add a list of groups to the cache dataset.
     *
     * @param[in] groups - The groups to add
     */
    void addGroups(const std::vector<Group>& groups);
};

} // namespace phosphor::fan::control::json
