#include "ldap_config.hpp"

#include "ldap_config_mgr.hpp"
#include "ldap_mapper_serialize.hpp"
#include "utils.hpp"

#include <cereal/archives/binary.hpp>
#include <cereal/types/string.hpp>
#include <cereal/types/vector.hpp>
#include <xyz/openbmc_project/Common/error.hpp>
#include <xyz/openbmc_project/User/Common/error.hpp>

#include <filesystem>
#include <fstream>
#include <sstream>

// Register class version
// From cereal documentation;
// "This macro should be placed at global scope"
CEREAL_CLASS_VERSION(phosphor::ldap::Config, CLASS_VERSION);

namespace phosphor
{
namespace ldap
{

constexpr auto nslcdService = "nslcd.service";
constexpr auto ldapScheme = "ldap";
constexpr auto ldapsScheme = "ldaps";
constexpr auto certObjPath = "/xyz/openbmc_project/certs/client/ldap/1";
constexpr auto certRootPath = "/xyz/openbmc_project/certs/client/ldap";
constexpr auto authObjPath = "/xyz/openbmc_project/certs/authority/ldap";
constexpr auto certIface = "xyz.openbmc_project.Certs.Certificate";
constexpr auto certProperty = "CertificateString";

using namespace phosphor::logging;
using namespace sdbusplus::xyz::openbmc_project::Common::Error;
namespace fs = std::filesystem;

using Argument = xyz::openbmc_project::Common::InvalidArgument;
using NotAllowed = sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
using NotAllowedArgument = xyz::openbmc_project::Common::NotAllowed;
using PrivilegeMappingExists = sdbusplus::xyz::openbmc_project::User::Common::
    Error::PrivilegeMappingExists;

using Line = std::string;
using Key = std::string;
using Val = std::string;
using ConfigInfo = std::map<Key, Val>;

Config::Config(sdbusplus::bus_t& bus, const char* path, const char* filePath,
               const char* caCertFile, const char* certFile, bool secureLDAP,
               std::string ldapServerURI, std::string ldapBindDN,
               std::string ldapBaseDN, std::string&& ldapBindDNPassword,
               ConfigIface::SearchScope ldapSearchScope,
               ConfigIface::Type ldapType, bool ldapServiceEnabled,
               std::string userNameAttr, std::string groupNameAttr,
               ConfigMgr& parent) :
    Ifaces(bus, path, Ifaces::action::defer_emit),
    secureLDAP(secureLDAP), ldapBindPassword(std::move(ldapBindDNPassword)),
    tlsCacertFile(caCertFile), tlsCertFile(certFile), configFilePath(filePath),
    objectPath(path), bus(bus), parent(parent),
    certificateInstalledSignal(
        bus, sdbusplus::bus::match::rules::interfacesAdded(certRootPath),
        std::bind(std::mem_fn(&Config::certificateInstalled), this,
                  std::placeholders::_1)),

    cacertificateInstalledSignal(
        bus, sdbusplus::bus::match::rules::interfacesAdded(authObjPath),
        std::bind(std::mem_fn(&Config::certificateInstalled), this,
                  std::placeholders::_1)),

    certificateChangedSignal(
        bus,
        sdbusplus::bus::match::rules::propertiesChanged(certObjPath, certIface),
        std::bind(std::mem_fn(&Config::certificateChanged), this,
                  std::placeholders::_1))
{
    ConfigIface::ldapServerURI(ldapServerURI);
    ConfigIface::ldapBindDN(ldapBindDN);
    ConfigIface::ldapBaseDN(ldapBaseDN);
    ConfigIface::ldapSearchScope(ldapSearchScope);
    ConfigIface::ldapType(ldapType);
    EnableIface::enabled(ldapServiceEnabled);
    ConfigIface::userNameAttribute(userNameAttr);
    ConfigIface::groupNameAttribute(groupNameAttr);
    // NOTE: Don't update the bindDN password under ConfigIface
    if (enabled())
    {
        writeConfig();
    }
    // save the config.
    configPersistPath = parent.dbusPersistentPath;
    configPersistPath += objectPath;

    // create the persistent directory
    fs::create_directories(configPersistPath);

    configPersistPath += "/config";

    serialize();

    // Emit deferred signal.
    this->emit_object_added();
    parent.startOrStopService(nslcdService, enabled());
}

Config::Config(sdbusplus::bus_t& bus, const char* path, const char* filePath,
               const char* caCertFile, const char* certFile,
               ConfigIface::Type ldapType, ConfigMgr& parent) :
    Ifaces(bus, path, Ifaces::action::defer_emit),
    secureLDAP(false), tlsCacertFile(caCertFile), tlsCertFile(certFile),
    configFilePath(filePath), objectPath(path), bus(bus), parent(parent),
    certificateInstalledSignal(
        bus, sdbusplus::bus::match::rules::interfacesAdded(certRootPath),
        std::bind(std::mem_fn(&Config::certificateInstalled), this,
                  std::placeholders::_1)),
    cacertificateInstalledSignal(
        bus, sdbusplus::bus::match::rules::interfacesAdded(authObjPath),
        std::bind(std::mem_fn(&Config::certificateInstalled), this,
                  std::placeholders::_1)),
    certificateChangedSignal(
        bus,
        sdbusplus::bus::match::rules::propertiesChanged(certObjPath, certIface),
        std::bind(std::mem_fn(&Config::certificateChanged), this,
                  std::placeholders::_1))
{
    ConfigIface::ldapType(ldapType);

    configPersistPath = parent.dbusPersistentPath;
    configPersistPath += objectPath;

    // create the persistent directory
    fs::create_directories(configPersistPath);

    configPersistPath += "/config";
}

void Config::certificateInstalled(sdbusplus::message_t& /*msg*/)
{
    try
    {
        if (enabled())
        {
            writeConfig();
        }
        parent.startOrStopService(nslcdService, enabled());
    }
    catch (const InternalFailure& e)
    {
        throw;
    }
    catch (const std::exception& e)
    {
        lg2::error("Exception: {ERR}", "ERR", e);
        elog<InternalFailure>();
    }
}

void Config::certificateChanged(sdbusplus::message_t& msg)
{
    std::string objectName;
    std::map<std::string, std::variant<std::string>> msgData;
    msg.read(objectName, msgData);
    auto valPropMap = msgData.find(certProperty);
    {
        if (valPropMap != msgData.end())
        {
            try
            {
                if (enabled())
                {
                    writeConfig();
                }
                parent.startOrStopService(nslcdService, enabled());
            }
            catch (const InternalFailure& e)
            {
                throw;
            }
            catch (const std::exception& e)
            {
                lg2::error("Exception: {ERR}", "ERR", e);
                elog<InternalFailure>();
            }
        }
    }
}

void Config::writeConfig()
{
    std::stringstream confData;
    auto isPwdTobeWritten = false;
    std::string userNameAttr;

    confData << "uid root\n";
    confData << "gid root\n\n";
    confData << "ldap_version 3\n\n";
    confData << "timelimit 30\n";
    confData << "bind_timelimit 30\n";
    confData << "pagesize 1000\n";
    confData << "referrals off\n\n";
    confData << "uri " << ldapServerURI() << "\n\n";
    confData << "base " << ldapBaseDN() << "\n\n";
    confData << "binddn " << ldapBindDN() << "\n";
    if (!ldapBindPassword.empty())
    {
        confData << "bindpw " << ldapBindPassword << "\n";
        isPwdTobeWritten = true;
    }
    confData << "\n";
    switch (ldapSearchScope())
    {
        case ConfigIface::SearchScope::sub:
            confData << "scope sub\n\n";
            break;
        case ConfigIface::SearchScope::one:
            confData << "scope one\n\n";
            break;
        case ConfigIface::SearchScope::base:
            confData << "scope base\n\n";
            break;
    }
    confData << "base passwd " << ldapBaseDN() << "\n";
    confData << "base shadow " << ldapBaseDN() << "\n\n";
    if (secureLDAP == true)
    {
        confData << "ssl on\n";
        confData << "tls_reqcert hard\n";
        if (fs::is_directory(tlsCacertFile.c_str()))
        {
            confData << "tls_cacertdir " << tlsCacertFile.c_str() << "\n";
        }
        else
        {
            confData << "tls_cacertfile " << tlsCacertFile.c_str() << "\n";
        }
        if (fs::exists(tlsCertFile.c_str()))
        {
            confData << "tls_cert " << tlsCertFile.c_str() << "\n";
            confData << "tls_key " << tlsCertFile.c_str() << "\n";
        }
    }
    else
    {
        confData << "ssl off\n";
    }
    confData << "\n";
    if (ldapType() == ConfigIface::Type::ActiveDirectory)
    {
        if (ConfigIface::userNameAttribute().empty())
        {
            ConfigIface::userNameAttribute("sAMAccountName");
        }
        if (ConfigIface::groupNameAttribute().empty())
        {
            ConfigIface::groupNameAttribute("primaryGroupID");
        }
        confData << "filter passwd (&(objectClass=user)(objectClass=person)"
                    "(!(objectClass=computer)))\n";
        confData
            << "filter group (|(objectclass=group)(objectclass=groupofnames) "
               "(objectclass=groupofuniquenames))\n";
        confData << "map passwd uid              "
                 << ConfigIface::userNameAttribute() << "\n";
        confData << "map passwd uidNumber        "
                    "objectSid:S-1-5-21-3623811015-3361044348-30300820\n";
        confData << "map passwd gidNumber        "
                 << ConfigIface::groupNameAttribute() << "\n";
        confData << "map passwd homeDirectory    \"/home/$sAMAccountName\"\n";
        confData << "map passwd gecos            displayName\n";
        confData << "map passwd loginShell       \"/bin/sh\"\n";
        confData << "map group gidNumber         "
                    "objectSid:S-1-5-21-3623811015-3361044348-30300820\n";
        confData << "map group cn                "
                 << ConfigIface::userNameAttribute() << "\n";
        confData << "nss_initgroups_ignoreusers ALLLOCAL\n";
    }
    else if (ldapType() == ConfigIface::Type::OpenLdap)
    {
        if (ConfigIface::userNameAttribute().empty())
        {
            ConfigIface::userNameAttribute("cn");
        }
        if (ConfigIface::groupNameAttribute().empty())
        {
            ConfigIface::groupNameAttribute("gidNumber");
        }
        confData << "filter passwd (objectclass=*)\n";
        confData << "map passwd gecos displayName\n";
        confData << "filter group (objectclass=posixGroup)\n";
        confData << "map passwd uid              "
                 << ConfigIface::userNameAttribute() << "\n";
        confData << "map passwd gidNumber        "
                 << ConfigIface::groupNameAttribute() << "\n";
        confData << "map passwd loginShell       \"/bin/sh\"\n";
        confData << "nss_initgroups_ignoreusers ALLLOCAL\n";
    }
    try
    {
        std::fstream stream(configFilePath.c_str(), std::fstream::out);
        // remove the read permission from others if password is being written.
        // nslcd forces this behaviour.
        auto permission = fs::perms::owner_read | fs::perms::owner_write |
                          fs::perms::group_read;
        if (isPwdTobeWritten)
        {
            fs::permissions(configFilePath, permission);
        }
        else
        {
            fs::permissions(configFilePath,
                            permission | fs::perms::others_read);
        }

        stream << confData.str();
        stream.flush();
        stream.close();
    }
    catch (const std::exception& e)
    {
        lg2::error("Exception: {ERR}", "ERR", e);
        elog<InternalFailure>();
    }
    return;
}

std::string Config::ldapBindDNPassword(std::string value)
{
    // Don't update the D-bus object, this is just to
    // facilitate if user wants to change the bind dn password
    // once d-bus object gets created.
    ldapBindPassword = value;
    try
    {
        if (enabled())
        {
            writeConfig();
            parent.startOrStopService(nslcdService, enabled());
        }
        serialize();
    }
    catch (const InternalFailure& e)
    {
        throw;
    }
    catch (const std::exception& e)
    {
        lg2::error("Exception: {ERR}", "ERR", e);
        elog<InternalFailure>();
    }
    return value;
}

std::string Config::ldapServerURI(std::string value)
{
    std::string val;
    try
    {
        if (value == ldapServerURI())
        {
            return value;
        }
        if (isValidLDAPURI(value, ldapsScheme))
        {
            secureLDAP = true;
        }
        else if (isValidLDAPURI(value, ldapScheme))
        {
            secureLDAP = false;
        }
        else
        {
            lg2::error("Bad LDAP Server URI {URI}", "URI", value);
            elog<InvalidArgument>(Argument::ARGUMENT_NAME("ldapServerURI"),
                                  Argument::ARGUMENT_VALUE(value.c_str()));
        }

        if (secureLDAP && !fs::exists(tlsCacertFile.c_str()))
        {
            lg2::error("LDAP server CA certificate not found at {PATH}", "PATH",
                       tlsCacertFile);
            elog<NoCACertificate>();
        }
        val = ConfigIface::ldapServerURI(value);
        if (enabled())
        {
            writeConfig();
            parent.startOrStopService(nslcdService, enabled());
        }
        // save the object.
        serialize();
    }
    catch (const InternalFailure& e)
    {
        throw;
    }
    catch (const InvalidArgument& e)
    {
        throw;
    }
    catch (const NoCACertificate& e)
    {
        throw;
    }
    catch (const std::exception& e)
    {
        lg2::error("Exception: {ERR}", "ERR", e);
        elog<InternalFailure>();
    }
    return val;
}

std::string Config::ldapBindDN(std::string value)
{
    std::string val;
    try
    {
        if (value == ldapBindDN())
        {
            return value;
        }

        if (value.empty())
        {
            lg2::error("'{BINDDN}' is not a valid LDAP BindDN", "BINDDN",
                       value);
            elog<InvalidArgument>(Argument::ARGUMENT_NAME("ldapBindDN"),
                                  Argument::ARGUMENT_VALUE(value.c_str()));
        }

        val = ConfigIface::ldapBindDN(value);
        if (enabled())
        {
            writeConfig();
            parent.startOrStopService(nslcdService, enabled());
        }
        // save the object.
        serialize();
    }
    catch (const InternalFailure& e)
    {
        throw;
    }
    catch (const InvalidArgument& e)
    {
        throw;
    }
    catch (const std::exception& e)
    {
        lg2::error("Exception: {ERR}", "ERR", e);
        elog<InternalFailure>();
    }
    return val;
}

std::string Config::ldapBaseDN(std::string value)
{
    std::string val;
    try
    {
        if (value == ldapBaseDN())
        {
            return value;
        }

        if (value.empty())
        {
            lg2::error("'{BASEDN}' is not a valid LDAP BaseDN", "BASEDN",
                       value);
            elog<InvalidArgument>(Argument::ARGUMENT_NAME("ldapBaseDN"),
                                  Argument::ARGUMENT_VALUE(value.c_str()));
        }

        val = ConfigIface::ldapBaseDN(value);
        if (enabled())
        {
            writeConfig();
            parent.startOrStopService(nslcdService, enabled());
        }
        // save the object.
        serialize();
    }
    catch (const InternalFailure& e)
    {
        throw;
    }
    catch (const InvalidArgument& e)
    {
        throw;
    }
    catch (const std::exception& e)
    {
        lg2::error("Exception: {ERR}", "ERR", e);
        elog<InternalFailure>();
    }
    return val;
}

ConfigIface::SearchScope Config::ldapSearchScope(ConfigIface::SearchScope value)
{
    ConfigIface::SearchScope val;
    try
    {
        if (value == ldapSearchScope())
        {
            return value;
        }

        val = ConfigIface::ldapSearchScope(value);
        if (enabled())
        {
            writeConfig();

            parent.startOrStopService(nslcdService, enabled());
        }
        // save the object.
        serialize();
    }
    catch (const InternalFailure& e)
    {
        throw;
    }
    catch (const std::exception& e)
    {
        lg2::error("Exception: {ERR}", "ERR", e);
        elog<InternalFailure>();
    }
    return val;
}

ConfigIface::Type Config::ldapType(ConfigIface::Type /*value*/)
{
    elog<NotAllowed>(NotAllowedArgument::REASON("ReadOnly Property"));
    return ldapType();
}

bool Config::enabled(bool value)
{
    if (value == enabled())
    {
        return value;
    }
    // Let parent decide that can we enable this config.
    // It may happen that other config is already enabled,
    // Current implementation support only one config can
    // be active at a time.
    return parent.enableService(*this, value);
}

bool Config::enableService(bool value)
{
    bool isEnable = false;
    try
    {
        isEnable = EnableIface::enabled(value);
        if (isEnable)
        {
            writeConfig();
        }
        parent.startOrStopService(nslcdService, value);
        serialize();
    }
    catch (const InternalFailure& e)
    {
        throw;
    }
    catch (const std::exception& e)
    {
        lg2::error("Exception: {ERR}", "ERR", e);
        elog<InternalFailure>();
    }
    return isEnable;
}

std::string Config::userNameAttribute(std::string value)
{
    std::string val;
    try
    {
        if (value == userNameAttribute())
        {
            return value;
        }

        val = ConfigIface::userNameAttribute(value);
        if (enabled())
        {
            writeConfig();

            parent.startOrStopService(nslcdService, enabled());
        }
        // save the object.
        serialize();
    }
    catch (const InternalFailure& e)
    {
        throw;
    }
    catch (const std::exception& e)
    {
        lg2::error("Exception: {ERR}", "ERR", e);
        elog<InternalFailure>();
    }
    return val;
}

std::string Config::groupNameAttribute(std::string value)
{
    std::string val;
    try
    {
        if (value == groupNameAttribute())
        {
            return value;
        }

        val = ConfigIface::groupNameAttribute(value);
        if (enabled())
        {
            writeConfig();

            parent.startOrStopService(nslcdService, enabled());
        }
        // save the object.
        serialize();
    }
    catch (const InternalFailure& e)
    {
        throw;
    }
    catch (const std::exception& e)
    {
        lg2::error("Exception: {ERR}", "ERR", e);
        elog<InternalFailure>();
    }
    return val;
}

template <class Archive>
void Config::save(Archive& archive, const std::uint32_t /*version*/) const
{
    archive(this->enabled());
    archive(ldapServerURI());
    archive(ldapBindDN());
    archive(ldapBaseDN());
    archive(ldapSearchScope());
    archive(ldapBindPassword);
    archive(userNameAttribute());
    archive(groupNameAttribute());
}

template <class Archive>
void Config::load(Archive& archive, const std::uint32_t /*version*/)
{
    bool bVal;
    archive(bVal);
    EnableIface::enabled(bVal);

    std::string str;
    archive(str);
    ConfigIface::ldapServerURI(str);

    archive(str);
    ConfigIface::ldapBindDN(str);

    archive(str);
    ConfigIface::ldapBaseDN(str);

    ConfigIface::SearchScope scope;
    archive(scope);
    ConfigIface::ldapSearchScope(scope);

    archive(str);
    ldapBindPassword = str;

    archive(str);
    ConfigIface::userNameAttribute(str);

    archive(str);
    ConfigIface::groupNameAttribute(str);
}

void Config::serialize()
{

    if (!fs::exists(configPersistPath.c_str()))
    {
        std::ofstream os(configPersistPath.string(),
                         std::ios::binary | std::ios::out);
        auto permission = fs::perms::owner_read | fs::perms::owner_write |
                          fs::perms::group_read;
        fs::permissions(configPersistPath, permission);
        cereal::BinaryOutputArchive oarchive(os);
        oarchive(*this);
    }
    else
    {
        std::ofstream os(configPersistPath.string(),
                         std::ios::binary | std::ios::out);
        cereal::BinaryOutputArchive oarchive(os);
        oarchive(*this);
    }
    return;
}

bool Config::deserialize()
{
    try
    {
        if (fs::exists(configPersistPath))
        {
            std::ifstream is(configPersistPath.c_str(),
                             std::ios::in | std::ios::binary);
            cereal::BinaryInputArchive iarchive(is);
            iarchive(*this);

            if (isValidLDAPURI(ldapServerURI(), ldapScheme))
            {
                secureLDAP = false;
            }
            else if (isValidLDAPURI(ldapServerURI(), ldapsScheme))
            {
                secureLDAP = true;
            }
            return true;
        }
        return false;
    }
    catch (const cereal::Exception& e)
    {
        lg2::error("Exception: {ERR}", "ERR", e);
        std::error_code ec;
        fs::remove(configPersistPath, ec);
        return false;
    }
    catch (const fs::filesystem_error& e)
    {
        return false;
    }
}

ObjectPath Config::create(std::string groupName, std::string privilege)
{
    checkPrivilegeMapper(groupName);
    checkPrivilegeLevel(privilege);

    entryId++;

    // Object path for the LDAP group privilege mapper entry
    fs::path mapperObjectPath = objectPath;
    mapperObjectPath /= "role_map";
    mapperObjectPath /= std::to_string(entryId);

    fs::path persistPath = parent.dbusPersistentPath;
    persistPath += mapperObjectPath;

    // Create mapping for LDAP privilege mapper entry
    auto entry = std::make_unique<LDAPMapperEntry>(
        bus, mapperObjectPath.string().c_str(), persistPath.string().c_str(),
        groupName, privilege, *this);

    phosphor::ldap::serialize(*entry, std::move(persistPath));

    PrivilegeMapperList.emplace(entryId, std::move(entry));
    return mapperObjectPath.string();
}

void Config::deletePrivilegeMapper(Id id)
{
    fs::path mapperObjectPath = objectPath;
    mapperObjectPath /= "role_map";
    mapperObjectPath /= std::to_string(id);

    fs::path persistPath = parent.dbusPersistentPath;
    persistPath += std::move(mapperObjectPath);

    // Delete the persistent representation of the privilege mapper.
    fs::remove(std::move(persistPath));

    PrivilegeMapperList.erase(id);
}
void Config::checkPrivilegeMapper(const std::string& groupName)
{
    if (groupName.empty())
    {
        lg2::error("Group name is empty");
        elog<InvalidArgument>(Argument::ARGUMENT_NAME("Group name"),
                              Argument::ARGUMENT_VALUE("Null"));
    }

    for (const auto& val : PrivilegeMapperList)
    {
        if (val.second.get()->groupName() == groupName)
        {
            lg2::error("Group name '{GROUPNAME}' already exists", "GROUPNAME",
                       groupName);
            elog<PrivilegeMappingExists>();
        }
    }
}

void Config::checkPrivilegeLevel(const std::string& privilege)
{
    if (privilege.empty())
    {
        lg2::error("Privilege level is empty");
        elog<InvalidArgument>(Argument::ARGUMENT_NAME("Privilege level"),
                              Argument::ARGUMENT_VALUE("Null"));
    }

    if (std::find(privMgr.begin(), privMgr.end(), privilege) == privMgr.end())
    {
        lg2::error("Invalid privilege '{PRIVILEGE}'", "PRIVILEGE", privilege);
        elog<InvalidArgument>(Argument::ARGUMENT_NAME("Privilege"),
                              Argument::ARGUMENT_VALUE(privilege.c_str()));
    }
}

void Config::restoreRoleMapping()
{
    namespace fs = std::filesystem;
    fs::path dir = parent.dbusPersistentPath;
    dir += objectPath;
    dir /= "role_map";

    if (!fs::exists(dir) || fs::is_empty(dir))
    {
        return;
    }

    for (auto& file : fs::directory_iterator(dir))
    {
        std::string id = file.path().filename().c_str();
        size_t idNum = std::stol(id);

        auto entryPath = objectPath + '/' + "role_map" + '/' + id;
        auto persistPath = parent.dbusPersistentPath + entryPath;
        auto entry = std::make_unique<LDAPMapperEntry>(
            bus, entryPath.c_str(), persistPath.c_str(), *this);
        if (phosphor::ldap::deserialize(file.path(), *entry))
        {
            entry->Interfaces::emit_object_added();
            PrivilegeMapperList.emplace(idNum, std::move(entry));
            if (idNum > entryId)
            {
                entryId = idNum;
            }
        }
    }
}

} // namespace ldap
} // namespace phosphor
