#include "config.h"

#include "snmp_conf_manager.hpp"

#include "snmp_serialize.hpp"
#include "snmp_util.hpp"
#include "xyz/openbmc_project/Common/error.hpp"

#include <arpa/inet.h>

#include <phosphor-logging/elog-errors.hpp>
#include <phosphor-logging/log.hpp>

#include <experimental/filesystem>

namespace phosphor
{
namespace network
{
namespace snmp
{

using namespace phosphor::logging;
using namespace sdbusplus::xyz::openbmc_project::Common::Error;
using Argument = xyz::openbmc_project::Common::InvalidArgument;

ConfManager::ConfManager(sdbusplus::bus::bus& bus, const char* objPath) :
    details::CreateIface(bus, objPath, true),
    dbusPersistentLocation(SNMP_CONF_PERSIST_PATH), bus(bus),
    objectPath(objPath)
{}

std::string ConfManager::client(std::string address, uint16_t port)
{
    // will throw exception if it is already configured.
    checkClientConfigured(address, port);

    lastClientId++;
    try
    {
        // just to check whether given address is valid or not.
        resolveAddress(address);
    }
    catch (InternalFailure& e)
    {
        log<level::ERR>("Not a valid address"),
            entry("ADDRESS=%s", address.c_str());
        elog<InvalidArgument>(Argument::ARGUMENT_NAME("Address"),
                              Argument::ARGUMENT_VALUE(address.c_str()));
    }

    // create the D-Bus object
    std::experimental::filesystem::path objPath;
    objPath /= objectPath;
    objPath /= std::to_string(lastClientId);

    auto client = std::make_unique<phosphor::network::snmp::Client>(
        bus, objPath.string().c_str(), *this, address, port);

    // save the D-Bus object
    serialize(lastClientId, *client, dbusPersistentLocation);

    this->clients.emplace(lastClientId, std::move(client));
    return objPath.string();
}

void ConfManager::checkClientConfigured(const std::string& address,
                                        uint16_t port)
{
    if (address.empty())
    {
        log<level::ERR>("Invalid address");
        elog<InvalidArgument>(Argument::ARGUMENT_NAME("ADDRESS"),
                              Argument::ARGUMENT_VALUE(address.c_str()));
    }

    for (const auto& val : clients)
    {
        if (val.second.get()->address() == address &&
            val.second.get()->port() == port)
        {
            log<level::ERR>("Client already exist");
            // TODO Add the error(Object already exist) in the D-Bus interface
            // then make the change here,meanwhile send the Internal Failure.
            elog<InvalidArgument>(
                Argument::ARGUMENT_NAME("ADDRESS"),
                Argument::ARGUMENT_VALUE("Client already exist."));
        }
    }
}

void ConfManager::deleteSNMPClient(Id id)
{
    auto it = clients.find(id);
    if (it == clients.end())
    {
        log<level::ERR>("Unable to delete the snmp client.",
                        entry("ID=%d", id));
        return;
    }

    std::error_code ec;
    // remove the persistent file
    fs::path fileName = dbusPersistentLocation;
    fileName /= std::to_string(id);

    if (fs::exists(fileName))
    {
        if (!fs::remove(fileName, ec))
        {
            log<level::ERR>("Unable to delete the file",
                            entry("FILE=%s", fileName.c_str()),
                            entry("ERROR=%d", ec.value()));
        }
    }
    else
    {
        log<level::ERR>("File doesn't exist",
                        entry("FILE=%s", fileName.c_str()));
    }
    // remove the D-Bus Object.
    this->clients.erase(it);
}

void ConfManager::restoreClients()
{
    if (!fs::exists(dbusPersistentLocation) ||
        fs::is_empty(dbusPersistentLocation))
    {
        return;
    }

    for (auto& confFile :
         fs::recursive_directory_iterator(dbusPersistentLocation))
    {
        if (!fs::is_regular_file(confFile))
        {
            continue;
        }

        auto managerID = confFile.path().filename().string();
        Id idNum = std::stol(managerID);

        fs::path objPath = objectPath;
        objPath /= managerID;
        auto manager =
            std::make_unique<Client>(bus, objPath.string().c_str(), *this);
        if (deserialize(confFile.path(), *manager))
        {
            manager->emit_object_added();
            this->clients.emplace(idNum, std::move(manager));
            if (idNum > lastClientId)
            {
                lastClientId = idNum;
            }
        }
    }
}

} // namespace snmp
} // namespace network
} // namespace phosphor
