#pragma once

#include "dhcp_configuration.hpp"
#include "ethernet_interface.hpp"
#include "routing_table.hpp"
#include "system_configuration.hpp"
#include "vlan_interface.hpp"
#include "xyz/openbmc_project/Network/VLAN/Create/server.hpp"

#include <filesystem>
#include <function2/function2.hpp>
#include <memory>
#include <sdbusplus/bus.hpp>
#include <string>
#include <utility>
#include <vector>
#include <xyz/openbmc_project/Common/FactoryReset/server.hpp>

namespace phosphor
{
namespace network
{

using SystemConfPtr = std::unique_ptr<SystemConfiguration>;
using DHCPConfPtr = std::unique_ptr<dhcp::Configuration>;

namespace fs = std::filesystem;
namespace details
{

template <typename T, typename U>
using ServerObject = typename sdbusplus::server::object_t<T, U>;

using VLANCreateIface = details::ServerObject<
    sdbusplus::xyz::openbmc_project::Network::VLAN::server::Create,
    sdbusplus::xyz::openbmc_project::Common::server::FactoryReset>;

} // namespace details

/** @class Manager
 *  @brief OpenBMC network manager implementation.
 */
class Manager : public details::VLANCreateIface
{
  public:
    Manager() = delete;
    Manager(const Manager&) = delete;
    Manager& operator=(const Manager&) = delete;
    Manager(Manager&&) = delete;
    Manager& operator=(Manager&&) = delete;
    virtual ~Manager() = default;

    /** @brief Constructor to put object onto bus at a dbus path.
     *  @param[in] bus - Bus to attach to.
     *  @param[in] objPath - Path to attach at.
     *  @param[in] dir - Network Configuration directory path.
     */
    Manager(sdbusplus::bus_t& bus, const char* objPath, const std::string& dir);

    ObjectPath vlan(IntfName interfaceName, uint32_t id) override;

    /** @brief write the network conf file with the in-memory objects.
     */
    void writeToConfigurationFile();

    /** @brief Fetch the interface and the ipaddress details
     *         from the system and create the ethernet interraces
     *         dbus object.
     */
    virtual void createInterfaces();

    /** @brief create child interface object and the system conf object.
     */
    void createChildObjects();

    /** @brief sets the network conf directory.
     *  @param[in] dirName - Absolute path of the directory.
     */
    void setConfDir(const fs::path& dir);

    /** @brief gets the network conf directory.
     */
    fs::path getConfDir()
    {
        return confDir;
    }

    /** @brief gets the system conf object.
     *
     */
    const SystemConfPtr& getSystemConf()
    {
        return systemConf;
    }

    /** @brief gets the dhcp conf object.
     *
     */
    const DHCPConfPtr& getDHCPConf()
    {
        return dhcpConf;
    }

    /** @brief create the default network files for each interface
     *  @return true if network file created else false
     */
    bool createDefaultNetworkFiles();

    /** @brief This function gets the MAC address from the VPD and
     *  sets it on the corresponding ethernet interface during first
     *  Boot, once it sets the MAC from VPD, it creates a file named
     *  firstBoot under /var/lib to make sure we dont run this function
     *  again.
     *
     *  @param[in] ethPair - Its a pair of ethernet interface name & the
     * corresponding MAC Address from the VPD
     *
     *  return - NULL
     */
    void setFistBootMACOnInterface(
        const std::pair<std::string, std::string>& ethPair);

    /** @brief Arms a timer to tell systemd-network to reload all of the network
     * configurations
     */
    virtual void reloadConfigs();

    /** @brief Tell systemd-network to reload all of the network configurations
     */
    void doReloadConfigs();

    /** @brief Returns the number of interfaces under this manager.
     *
     * @return the number of interfaces managed by this manager.
     */
    int getInterfaceCount()
    {
        return interfaces.size();
    }

    /** @brief Does the requested interface exist under this manager?
     *
     * @param[in] intf - the interface name to check.
     * @return true if found, false otherwise.
     */
    bool hasInterface(const std::string& intf)
    {
        return (interfaces.find(intf) != interfaces.end());
    }

    /** @brief Get the routing table owned by the manager
     *
     * @return Routing table reference.
     */
    inline const auto& getRouteTable() const
    {
        return routeTable;
    }

    /** @brief Adds a hook that runs immediately prior to reloading
     *
     *  @param[in] hook - The hook to execute before reloading
     */
    inline void addReloadPreHook(fu2::unique_function<void()>&& hook)
    {
        reloadPreHooks.push_back(std::move(hook));
    }

  protected:
    /** @brief Persistent sdbusplus DBus bus connection. */
    sdbusplus::bus_t& bus;

    /** @brief Persistent map of EthernetInterface dbus objects and their names
     */
    std::map<IntfName, std::shared_ptr<EthernetInterface>> interfaces;

    /** @brief BMC network reset - resets network configuration for BMC. */
    void reset() override;

    /** @brief Path of Object. */
    std::string objectPath;

    /** @brief pointer to system conf object. */
    SystemConfPtr systemConf = nullptr;

    /** @brief pointer to dhcp conf object. */
    DHCPConfPtr dhcpConf = nullptr;

    /** @brief Network Configuration directory. */
    fs::path confDir;

    /** @brief The routing table */
    route::Table routeTable;

    /** @brief List of hooks to execute during the next reload */
    std::vector<fu2::unique_function<void()>> reloadPreHooks;
};

} // namespace network
} // namespace phosphor
