/*
// Copyright (c) 2018 Intel 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 "users.hpp"

#include <boost/process/child.hpp>
#include <boost/process/io.hpp>
#include <phosphor-logging/elog-errors.hpp>
#include <phosphor-logging/elog.hpp>
#include <phosphor-logging/lg2.hpp>
#include <sdbusplus/bus.hpp>
#include <sdbusplus/server/object.hpp>
#include <xyz/openbmc_project/Common/error.hpp>
#include <xyz/openbmc_project/User/AccountPolicy/server.hpp>
#include <xyz/openbmc_project/User/Manager/server.hpp>

#include <span>
#include <string>
#include <unordered_map>
#include <variant>
#include <vector>

namespace phosphor
{
namespace user
{

inline constexpr size_t ipmiMaxUsers = 15;
inline constexpr size_t maxSystemUsers = 30;
inline constexpr uint8_t minPasswdLength = 8;
inline constexpr size_t maxSystemGroupNameLength = 32;
inline constexpr size_t maxSystemGroupCount = 64;

using UserMgrIface = sdbusplus::xyz::openbmc_project::User::server::Manager;
using UserSSHLists =
    std::pair<std::vector<std::string>, std::vector<std::string>>;
using AccountPolicyIface =
    sdbusplus::xyz::openbmc_project::User::server::AccountPolicy;

using Ifaces = sdbusplus::server::object_t<UserMgrIface, AccountPolicyIface>;

using Privilege = std::string;
using GroupList = std::vector<std::string>;
using UserEnabled = bool;
using PropertyName = std::string;
using ServiceEnabled = bool;

using UserInfo = std::variant<Privilege, GroupList, UserEnabled>;
using UserInfoMap = std::map<PropertyName, UserInfo>;

using DbusUserObjPath = sdbusplus::message::object_path;

using DbusUserPropVariant = std::variant<Privilege, ServiceEnabled>;

using DbusUserObjProperties = std::map<PropertyName, DbusUserPropVariant>;

using Interface = std::string;

using DbusUserObjValue = std::map<Interface, DbusUserObjProperties>;

using DbusUserObj = std::map<DbusUserObjPath, DbusUserObjValue>;

std::string getCSVFromVector(std::span<const std::string> vec);

bool removeStringFromCSV(std::string& csvStr, const std::string& delStr);

template <typename... ArgTypes>
std::vector<std::string> executeCmd(const char* path, ArgTypes&&... tArgs)
{
    std::vector<std::string> stdOutput;
    boost::process::ipstream stdOutStream;
    boost::process::child execProg(path, const_cast<char*>(tArgs)...,
                                   boost::process::std_out > stdOutStream);
    std::string stdOutLine;

    while (stdOutStream && std::getline(stdOutStream, stdOutLine) &&
           !stdOutLine.empty())
    {
        stdOutput.emplace_back(stdOutLine);
    }

    execProg.wait();

    int retCode = execProg.exit_code();
    if (retCode)
    {
        lg2::error("Command {PATH} execution failed, return code {RETCODE}",
                   "PATH", path, "RETCODE", retCode);
        phosphor::logging::elog<
            sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure>();
    }

    return stdOutput;
}

/** @class UserMgr
 *  @brief Responsible for managing user accounts over the D-Bus interface.
 */
class UserMgr : public Ifaces
{
  public:
    UserMgr() = delete;
    ~UserMgr() = default;
    UserMgr(const UserMgr&) = delete;
    UserMgr& operator=(const UserMgr&) = delete;
    UserMgr(UserMgr&&) = delete;
    UserMgr& operator=(UserMgr&&) = delete;

    /** @brief Constructs UserMgr object.
     *
     *  @param[in] bus  - sdbusplus handler
     *  @param[in] path - D-Bus path
     */
    UserMgr(sdbusplus::bus_t& bus, const char* path);

    /** @brief create user method.
     *  This method creates a new user as requested
     *
     *  @param[in] userName - Name of the user which has to be created
     *  @param[in] groupNames - Group names list, to which user has to be added.
     *  @param[in] priv - Privilege of the user.
     *  @param[in] enabled - State of the user enabled / disabled.
     */
    void createUser(std::string userName, std::vector<std::string> groupNames,
                    std::string priv, bool enabled) override;

    /** @brief rename user method.
     *  This method renames the user as requested
     *
     *  @param[in] userName - current name of the user
     *  @param[in] newUserName - new user name to which it has to be renamed.
     */
    void renameUser(std::string userName, std::string newUserName) override;

    /** @brief delete user method.
     *  This method deletes the user as requested
     *
     *  @param[in] userName - Name of the user which has to be deleted
     */
    void deleteUser(std::string userName);

    /** @brief Update user groups & privilege.
     *  This method updates user groups & privilege
     *
     *  @param[in] userName - user name, for which update is requested
     *  @param[in] groupName - Group to be updated..
     *  @param[in] priv - Privilege to be updated.
     */
    void updateGroupsAndPriv(const std::string& userName,
                             std::vector<std::string> groups,
                             const std::string& priv);

    /** @brief Update user enabled state.
     *  This method enables / disables user
     *
     *  @param[in] userName - user name, for which update is requested
     *  @param[in] enabled - enable / disable the user
     */
    void userEnable(const std::string& userName, bool enabled);

    /** @brief get user enabled state
     *  method to get user enabled state.
     *
     *  @param[in] userName - name of the user
     *  @return - user enabled status (true/false)
     */
    virtual bool isUserEnabled(const std::string& userName);

    /** @brief update minimum password length requirement
     *
     *  @param[in] val - minimum password length
     *  @return - minimum password length
     */
    uint8_t minPasswordLength(uint8_t val) override;

    /** @brief update old password history count
     *
     *  @param[in] val - number of times old passwords has to be avoided
     *  @return - number of times old password has to be avoided
     */
    uint8_t rememberOldPasswordTimes(uint8_t val) override;

    /** @brief update maximum number of failed login attempt before locked
     *  out.
     *
     *  @param[in] val - number of allowed attempt
     *  @return - number of allowed attempt
     */
    uint16_t maxLoginAttemptBeforeLockout(uint16_t val) override;

    /** @brief update timeout to unlock the account
     *
     *  @param[in] val - value in seconds
     *  @return - value in seconds
     */
    uint32_t accountUnlockTimeout(uint32_t val) override;

    /** @brief parses the faillock output for locked user status
     *
     * @param[in] - output from faillock for the user
     * @return - true / false indicating user locked / un-locked
     **/
    bool parseFaillockForLockout(
        const std::vector<std::string>& faillockOutput);

    /** @brief lists user locked state for failed attempt
     *
     * @param[in] - user name
     * @return - true / false indicating user locked / un-locked
     **/
    virtual bool userLockedForFailedAttempt(const std::string& userName);

    /** @brief lists user locked state for failed attempt
     *
     * @param[in]: user name
     * @param[in]: value - false -unlock user account, true - no action taken
     **/
    bool userLockedForFailedAttempt(const std::string& userName,
                                    const bool& value);

    /** @brief shows if the user's password is expired
     *
     * @param[in]: user name
     * @return - true / false indicating user password expired
     **/
    virtual bool userPasswordExpired(const std::string& userName);

    /** @brief returns user info
     * Checks if user is local user, then returns map of properties of user.
     * like user privilege, list of user groups, user enabled state and user
     * locked state. If its not local user, then it checks if its a ldap user,
     * then it gets the privilege mapping of the LDAP group.
     *
     * @param[in] - user name
     * @return -  map of user properties
     **/
    UserInfoMap getUserInfo(std::string userName) override;

    /** @brief get IPMI user count
     *  method to get IPMI user count
     *
     * @return - returns user count
     */
    virtual size_t getIpmiUsersCount(void);

    void createGroup(std::string groupName) override;

    void deleteGroup(std::string groupName) override;

    static std::vector<std::string> readAllGroupsOnSystem();

  protected:
    /** @brief get pam argument value
     *  method to get argument value from pam configuration
     *
     *  @param[in] moduleName - name of the module from where arg has to be read
     *  @param[in] argName - argument name
     *  @param[out] argValue - argument value
     *
     *  @return 0 - success state of the function
     */
    int getPamModuleArgValue(const std::string& moduleName,
                             const std::string& argName, std::string& argValue);

    /** @brief get pam argument value
     *  method to get argument value from pam configuration
     *
     *  @param[in] confFile - path of the module config file from where arg has
     * to be read
     *  @param[in] argName - argument name
     *  @param[out] argValue - argument value
     *
     *  @return 0 - success state of the function
     */
    int getPamModuleConfValue(const std::string& confFile,
                              const std::string& argName,
                              std::string& argValue);

    /** @brief set pam argument value
     *  method to set argument value in pam configuration
     *
     *  @param[in] moduleName - name of the module in which argument value has
     * to be set
     *  @param[in] argName - argument name
     *  @param[out] argValue - argument value
     *
     *  @return 0 - success state of the function
     */
    int setPamModuleArgValue(const std::string& moduleName,
                             const std::string& argName,
                             const std::string& argValue);

    /** @brief set pam argument value
     *  method to set argument value in pam configuration
     *
     *  @param[in] confFile - path of the module config file in which argument
     * value has to be set
     *  @param[in] argName - argument name
     *  @param[out] argValue - argument value
     *
     *  @return 0 - success state of the function
     */
    int setPamModuleConfValue(const std::string& confFile,
                              const std::string& argName,
                              const std::string& argValue);

    /** @brief check for user presence
     *  method to check for user existence
     *
     *  @param[in] userName - name of the user
     *  @return -true if user exists and false if not.
     */
    bool isUserExist(const std::string& userName);

    size_t getNonIpmiUsersCount();

    /** @brief check user exists
     *  method to check whether user exist, and throw if not.
     *
     *  @param[in] userName - name of the user
     */
    void throwForUserDoesNotExist(const std::string& userName);

    /** @brief check user does not exist
     *  method to check whether does not exist, and throw if exists.
     *
     *  @param[in] userName - name of the user
     */
    void throwForUserExists(const std::string& userName);

    /** @brief check user name constraints
     *  method to check user name constraints and throw if failed.
     *
     *  @param[in] userName - name of the user
     *  @param[in] groupNames - user groups
     */
    void throwForUserNameConstraints(
        const std::string& userName,
        const std::vector<std::string>& groupNames);

    /** @brief check group user count
     *  method to check max group user count, and throw if limit reached
     *
     *  @param[in] groupNames - group name
     */
    void throwForMaxGrpUserCount(const std::vector<std::string>& groupNames);

    virtual void executeUserAdd(const char* userName, const char* groups,
                                bool sshRequested, bool enabled);

    virtual void executeUserDelete(const char* userName);

    /** @brief clear user's failure records
     *  method to clear user fail records and throw if failed.
     *
     *  @param[in] userName - name of the user
     */
    virtual void executeUserClearFailRecords(const char* userName);

    virtual void executeUserRename(const char* userName,
                                   const char* newUserName);

    virtual void executeUserModify(const char* userName, const char* newGroups,
                                   bool sshRequested);

    virtual void executeUserModifyUserEnable(const char* userName,
                                             bool enabled);

    virtual void executeGroupCreation(const char* groupName);

    virtual void executeGroupDeletion(const char* groupName);

    virtual std::vector<std::string> getFailedAttempt(const char* userName);

    /** @brief check for valid privielge
     *  method to check valid privilege, and throw if invalid
     *
     *  @param[in] priv - privilege of the user
     */
    void throwForInvalidPrivilege(const std::string& priv);

    /** @brief check for valid groups
     *  method to check valid groups, and throw if invalid
     *
     *  @param[in] groupNames - user groups
     */
    void throwForInvalidGroups(const std::vector<std::string>& groupName);

    void initializeAccountPolicy();

    /** @brief checks if the group creation meets all constraints
     * @param groupName - group to check
     */
    void checkCreateGroupConstraints(const std::string& groupName);

    /** @brief checks if the group deletion meets all constraints
     * @param groupName - group to check
     */
    void checkDeleteGroupConstraints(const std::string& groupName);

    /** @brief checks if the group name is legal and whether it's allowed to
     * change. The daemon doesn't allow arbitrary group to be created
     * @param groupName - group to check
     */
    void checkAndThrowForDisallowedGroupCreation(const std::string& groupName);

  private:
    /** @brief sdbusplus handler */
    sdbusplus::bus_t& bus;

    /** @brief object path */
    const std::string path;

    /** @brief privilege manager container */
    const std::vector<std::string> privMgr = {"priv-admin", "priv-operator",
                                              "priv-user"};

    /** @brief groups manager container */
    std::vector<std::string> groupsMgr;

    /** @brief map container to hold users object */
    using UserName = std::string;
    std::unordered_map<UserName, std::unique_ptr<phosphor::user::Users>>
        usersList;

    /** @brief get users in group
     *  method to get group user list
     *
     *  @param[in] groupName - group name
     *
     *  @return userList  - list of users in the group.
     */
    std::vector<std::string> getUsersInGroup(const std::string& groupName);

    /** @brief get user & SSH users list
     *  method to get the users and ssh users list.
     *
     *@return - vector of User & SSH user lists
     */
    UserSSHLists getUserAndSshGrpList(void);

    /** @brief initialize the user manager objects
     *  method to initialize the user manager objects accordingly
     *
     */
    void initUserObjects(void);

    /** @brief get service name
     *  method to get dbus service name
     *
     *  @param[in] path - object path
     *  @param[in] intf - interface
     *  @return - service name
     */
    std::string getServiceName(std::string&& path, std::string&& intf);

    /** @brief get primary group ID of specified user
     *
     * @param[in] - userName
     * @return - primary group ID
     */
    virtual gid_t getPrimaryGroup(const std::string& userName) const;

    /** @brief check whether if the user is a member of the group
     *
     * @param[in] - userName
     * @param[in] - ID of the user's primary group
     * @param[in] - groupName
     * @return - true if the user is a member of the group
     */
    virtual bool isGroupMember(const std::string& userName, gid_t primaryGid,
                               const std::string& groupName) const;

  protected:
    /** @brief get privilege mapper object
     *  method to get dbus privilege mapper object
     *
     *  @return - map of user object
     */
    virtual DbusUserObj getPrivilegeMapperObject(void);

    friend class TestUserMgr;

    std::string faillockConfigFile;
    std::string pwHistoryConfigFile;
    std::string pwQualityConfigFile;
};

} // namespace user
} // namespace phosphor
