/**
 * 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 "../utils/flight_recorder.hpp"
#include "../zone.hpp"
#include "config_base.hpp"
#include "group.hpp"

#include <fmt/format.h>

#include <nlohmann/json.hpp>
#include <phosphor-logging/log.hpp>

#include <algorithm>
#include <functional>
#include <iterator>
#include <map>
#include <memory>
#include <numeric>

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

using json = nlohmann::json;
using namespace phosphor::logging;

/**
 * @class ActionParseError - A parsing error exception
 *
 * A parsing error exception that can be used to terminate the application
 * due to not being able to successfully parse a configured action.
 */
class ActionParseError : public std::runtime_error
{
  public:
    ActionParseError() = delete;
    ActionParseError(const ActionParseError&) = delete;
    ActionParseError(ActionParseError&&) = delete;
    ActionParseError& operator=(const ActionParseError&) = delete;
    ActionParseError& operator=(ActionParseError&&) = delete;
    ~ActionParseError() = default;

    /**
     * @brief Action parsing error object
     *
     * When parsing an action from the JSON configuration, any critical
     * attributes that fail to be parsed for an action can throw an
     * ActionParseError exception to log the parsing failure details and
     * terminate the application.
     *
     * @param[in] name - Name of the action
     * @param[in] details - Additional details of the parsing error
     */
    ActionParseError(const std::string& name, const std::string& details) :
        std::runtime_error(
            fmt::format("Failed to parse action {} [{}]", name, details)
                .c_str())
    {}
};

/**
 * @brief Function used in creating action objects
 *
 * @param[in] jsonObj - JSON object for the action
 * @param[in] groups - Groups of dbus objects the action uses
 * @param[in] zones - Zones the action runs against
 *
 * Creates an action object given the JSON configuration, list of groups and
 * sets the zones the action should run against.
 */
template <typename T>
std::unique_ptr<T>
    createAction(const json& jsonObj, const std::vector<Group>& groups,
                 std::vector<std::reference_wrapper<Zone>>& zones)
{
    // Create the action and set its list of zones
    auto action = std::make_unique<T>(jsonObj, groups);
    action->setZones(zones);
    return action;
}

/**
 * @class ActionBase - Base action object
 *
 * Base class for fan control's event actions
 */
class ActionBase : public ConfigBase
{
  public:
    ActionBase() = delete;
    ActionBase(const ActionBase&) = delete;
    ActionBase(ActionBase&&) = delete;
    ActionBase& operator=(const ActionBase&) = delete;
    ActionBase& operator=(ActionBase&&) = delete;
    virtual ~ActionBase() = default;

    /**
     * @brief Base action object
     *
     * @param[in] jsonObj - JSON object containing name and any profiles
     * @param[in] groups - Groups of dbus objects the action uses
     *
     * All actions derived from this base action object must be given a name
     * that uniquely identifies the action. Optionally, a configured action can
     * have a list of explicit profiles it should be included in, otherwise
     * always include the action where no profiles are given.
     */
    ActionBase(const json& jsonObj, const std::vector<Group>& groups) :
        ConfigBase(jsonObj), _groups(groups),
        _uniqueName(getName() + "-" + std::to_string(_actionCount++))
    {}

    /**
     * @brief Get the groups configured on the action
     *
     * @return List of groups
     */
    inline const auto& getGroups() const
    {
        return _groups;
    }

    /**
     * @brief Set the zones the action is run against
     *
     * @param[in] zones - Zones the action runs against
     *
     * By default, the zones are set when the action object is created
     */
    virtual void setZones(std::vector<std::reference_wrapper<Zone>>& zones)
    {
        _zones = zones;
    }

    /**
     * @brief Add a zone to the list of zones the action is run against if its
     * not already there
     *
     * @param[in] zone - Zone to add
     */
    virtual void addZone(Zone& zone)
    {
        auto itZone =
            std::find_if(_zones.begin(), _zones.end(),
                         [&zone](std::reference_wrapper<Zone>& z) {
                             return z.get().getName() == zone.getName();
                         });
        if (itZone == _zones.end())
        {
            _zones.emplace_back(std::reference_wrapper<Zone>(zone));
        }
    }

    /**
     * @brief Run the action
     *
     * Run the action function associated to the derived action object
     * that performs a specific tasks on a zone configured by a user.
     *
     * @param[in] zone - Zone to run the action on
     */
    virtual void run(Zone& zone) = 0;

    /**
     * @brief Trigger the action to run against all of its zones
     *
     * This is the function used by triggers to run the actions against all the
     * zones that were configured for the action to run against.
     */
    void run()
    {
        std::for_each(_zones.begin(), _zones.end(),
                      [this](Zone& zone) { this->run(zone); });
    }

    /**
     * @brief Returns a unique name for the action.
     *
     * @return std::string - The name
     */
    const std::string& getUniqueName() const
    {
        return _uniqueName;
    }

    /**
     * @brief Set the name of the owning Event.
     *
     * Adds it to the unique name in parentheses. If desired,
     * the action child classes can do something else with it.
     *
     * @param[in] name - The event name
     */
    virtual void setEventName(const std::string& name)
    {
        if (!name.empty())
        {
            _uniqueName += '(' + name + ')';
        }
    }

  protected:
    /**
     * @brief Logs a message to the flight recorder using
     *        the unique name of the action.
     *
     * @param[in] message - The message to log
     */
    void record(const std::string& message) const
    {
        FlightRecorder::instance().log(getUniqueName(), message);
    }

    /* Groups configured on the action */
    const std::vector<Group> _groups;

  private:
    /* Zones configured on the action */
    std::vector<std::reference_wrapper<Zone>> _zones;

    /* Unique name of the action.
     * It's just the name plus _actionCount at the time of action creation. */
    std::string _uniqueName;

    /* Running count of all actions */
    static inline size_t _actionCount = 0;
};

/**
 * @class ActionFactory - Factory for actions
 *
 * Factory that registers and retrieves actions based on a given name.
 */
class ActionFactory
{
  public:
    ActionFactory() = delete;
    ActionFactory(const ActionFactory&) = delete;
    ActionFactory(ActionFactory&&) = delete;
    ActionFactory& operator=(const ActionFactory&) = delete;
    ActionFactory& operator=(ActionFactory&&) = delete;
    ~ActionFactory() = default;

    /**
     * @brief Registers an action
     *
     * Registers an action as being available for configuration use. The action
     * is registered by its name and a function used to create the action
     * object. An action fails to be registered when another action of the same
     * name has already been registered. Actions with the same name would cause
     * undefined behavior, therefore are not allowed.
     *
     * Actions are registered prior to starting main().
     *
     * @param[in] name - Name of the action to register
     *
     * @return The action was registered, otherwise an exception is thrown.
     */
    template <typename T>
    static bool regAction(const std::string& name)
    {
        auto it = actions.find(name);
        if (it == actions.end())
        {
            actions[name] = &createAction<T>;
        }
        else
        {
            log<level::ERR>(
                fmt::format("Action '{}' is already registered", name).c_str());
            throw std::runtime_error("Actions with the same name found");
        }

        return true;
    }

    /**
     * @brief Gets a registered action's object
     *
     * Gets a registered action's object of a given name from the JSON
     * configuration data provided.
     *
     * @param[in] name - Name of the action to create/get
     * @param[in] jsonObj - JSON object for the action
     * @param[in] groups - Groups of dbus objects the action uses
     * @param[in] zones - Zones the action runs against
     *
     * @return Pointer to the action object.
     */
    static std::unique_ptr<ActionBase>
        getAction(const std::string& name, const json& jsonObj,
                  const std::vector<Group>& groups,
                  std::vector<std::reference_wrapper<Zone>>&& zones)
    {
        auto it = actions.find(name);
        if (it != actions.end())
        {
            return it->second(jsonObj, groups, zones);
        }
        else
        {
            // Construct list of available actions
            auto acts = std::accumulate(
                std::next(actions.begin()), actions.end(),
                actions.begin()->first, [](auto list, auto act) {
                    return std::move(list) + ", " + act.first;
                });
            log<level::ERR>(
                fmt::format("Action '{}' is not registered", name).c_str(),
                entry("AVAILABLE_ACTIONS=%s", acts.c_str()));
            throw std::runtime_error("Unsupported action name given");
        }
    }

  private:
    /* Map to store the available actions and their creation functions */
    static inline std::map<std::string,
                           std::function<std::unique_ptr<ActionBase>(
                               const json&, const std::vector<Group>&,
                               std::vector<std::reference_wrapper<Zone>>&)>>
        actions;
};

/**
 * @class ActionRegister - Registers an action class
 *
 * Base action registration class that is extended by an action object so
 * that action is registered and available for use.
 */
template <typename T>
class ActionRegister
{
  public:
    ActionRegister(const ActionRegister&) = delete;
    ActionRegister(ActionRegister&&) = delete;
    ActionRegister& operator=(const ActionRegister&) = delete;
    ActionRegister& operator=(ActionRegister&&) = delete;
    virtual ~ActionRegister() = default;
    ActionRegister()
    {
        // Templates instantiated when used, need to assign a value
        // here so the compiler doesnt remove it
        registered = true;
    }

  private:
    /* Register actions in the factory */
    static inline bool registered = ActionFactory::regAction<T>(T::name);
};

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