/*
// 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 <bitset>
#include <ipmid/api.hpp>
#include <ipmid/types.hpp>
#include <string>

namespace ipmi
{

// TODO: Has to be replaced with proper channel number assignment logic
/**
 * @enum Channel Id
 */
enum class EChannelID : uint8_t
{
    chanLan1 = 0x01
};

static constexpr uint8_t invalidUserId = 0xFF;
static constexpr uint8_t reservedUserId = 0x0;
static constexpr uint8_t ipmiMaxUserName = 16;
static constexpr uint8_t ipmiMaxUsers = 15;
static constexpr uint8_t ipmiMaxChannels = 16;
static constexpr uint8_t maxIpmi20PasswordSize = 20;
static constexpr uint8_t maxIpmi15PasswordSize = 16;
static constexpr uint8_t payloadsPerByte = 8;

/** @struct PrivAccess
 *
 *  User privilege related access data as per IPMI specification.(refer spec
 * sec 22.26)
 */
struct PrivAccess
{
#if BYTE_ORDER == LITTLE_ENDIAN
    uint8_t privilege : 4;
    uint8_t ipmiEnabled : 1;
    uint8_t linkAuthEnabled : 1;
    uint8_t accessCallback : 1;
    uint8_t reserved : 1;
#endif
#if BYTE_ORDER == BIG_ENDIAN
    uint8_t reserved : 1;
    uint8_t accessCallback : 1;
    uint8_t linkAuthEnabled : 1;
    uint8_t ipmiEnabled : 1;
    uint8_t privilege : 4;
#endif
} __attribute__((packed));

/** @struct UserPayloadAccess
 *
 *  Structure to denote payload access restrictions applicable for a
 *  given user and channel. (refer spec sec 24.6)
 */
struct PayloadAccess
{
    std::bitset<payloadsPerByte> stdPayloadEnables1;
    std::bitset<payloadsPerByte> stdPayloadEnables2Reserved;
    std::bitset<payloadsPerByte> oemPayloadEnables1;
    std::bitset<payloadsPerByte> oemPayloadEnables2Reserved;
};

/** @brief initializes user management
 *
 *  @return ccSuccess for success, others for failure.
 */
Cc ipmiUserInit();

/** @brief The ipmi get user password layer call
 *
 *  @param[in] userName - user name
 *
 *  @return password or empty string
 */
SecureString ipmiUserGetPassword(const std::string& userName);

/** @brief The IPMI call to clear password entry associated with specified
 * username
 *
 *  @param[in] userName - user name to be removed
 *
 *  @return 0 on success, non-zero otherwise.
 */
Cc ipmiClearUserEntryPassword(const std::string& userName);

/** @brief The IPMI call to reuse password entry for the renamed user
 *  to another one
 *
 *  @param[in] userName - user name which has to be renamed
 *  @param[in] newUserName - new user name
 *
 *  @return 0 on success, non-zero otherwise.
 */
Cc ipmiRenameUserEntryPassword(const std::string& userName,
                               const std::string& newUserName);

/** @brief determines valid userId
 *
 *  @param[in] userId - user id
 *
 *  @return true if valid, false otherwise
 */
bool ipmiUserIsValidUserId(const uint8_t userId);

/** @brief determines valid privilege level
 *
 *  @param[in] priv - privilege level
 *
 *  @return true if valid, false otherwise
 */
bool ipmiUserIsValidPrivilege(const uint8_t priv);

/** @brief get user id corresponding to the user name
 *
 *  @param[in] userName - user name
 *
 *  @return userid. Will return 0xff if no user id found
 */
uint8_t ipmiUserGetUserId(const std::string& userName);

/** @brief set's user name
 *  This API is deprecated
 */
Cc ipmiUserSetUserName(const uint8_t userId, const char* userName)
    __attribute__((deprecated));

/** @brief set's user name
 *
 *  @param[in] userId - user id
 *  @param[in] userName - user name
 *
 *  @return ccSuccess for success, others for failure.
 */
Cc ipmiUserSetUserName(const uint8_t userId, const std::string& userName);

/** @brief set user password
 *
 *  @param[in] userId - user id
 *  @param[in] userPassword - New Password
 *
 *  @return ccSuccess for success, others for failure.
 */
Cc ipmiUserSetUserPassword(const uint8_t userId, const char* userPassword);

/** @brief set special user password (non-ipmi accounts)
 *
 *  @param[in] userName - user name
 *  @param[in] userPassword - New Password
 *
 *  @return ccSuccess for success, others for failure.
 */
Cc ipmiSetSpecialUserPassword(const std::string& userName,
                              const SecureString& userPassword);

/** @brief get user name
 *
 *  @param[in] userId - user id
 *  @param[out] userName - user name
 *
 *  @return ccSuccess for success, others for failure.
 */
Cc ipmiUserGetUserName(const uint8_t userId, std::string& userName);

/** @brief provides available fixed, max, and enabled user counts
 *
 *  @param[out] maxChUsers - max channel users
 *  @param[out] enabledUsers - enabled user count
 *  @param[out] fixedUsers - fixed user count
 *
 *  @return ccSuccess for success, others for failure.
 */
Cc ipmiUserGetAllCounts(uint8_t& maxChUsers, uint8_t& enabledUsers,
                        uint8_t& fixedUsers);

/** @brief function to update user enabled state
 *
 *  @param[in] userId - user id
 *..@param[in] state - state of the user to be updated, true - user enabled.
 *
 *  @return ccSuccess for success, others for failure.
 */
Cc ipmiUserUpdateEnabledState(const uint8_t userId, const bool& state);

/** @brief determines whether user is enabled
 *
 *  @param[in] userId - user id
 *..@param[out] state - state of the user
 *
 *  @return ccSuccess for success, others for failure.
 */
Cc ipmiUserCheckEnabled(const uint8_t userId, bool& state);

/** @brief provides user privilege access data
 *
 *  @param[in] userId - user id
 *  @param[in] chNum - channel number
 *  @param[out] privAccess - privilege access data
 *
 *  @return ccSuccess for success, others for failure.
 */
Cc ipmiUserGetPrivilegeAccess(const uint8_t userId, const uint8_t chNum,
                              PrivAccess& privAccess);

/** @brief sets user privilege access data
 *
 *  @param[in] userId - user id
 *  @param[in] chNum - channel number
 *  @param[in] privAccess - privilege access data
 *  @param[in] otherPrivUpdate - flags to indicate other fields update
 *
 *  @return ccSuccess for success, others for failure.
 */
Cc ipmiUserSetPrivilegeAccess(const uint8_t userId, const uint8_t chNum,
                              const PrivAccess& privAccess,
                              const bool& otherPrivUpdate);

/** @brief check for user pam authentication. This is to determine, whether user
 * is already locked out for failed login attempt
 *
 *  @param[in] username - username
 *  @param[in] password - password
 *
 *  @return status
 */
bool ipmiUserPamAuthenticate(std::string_view userName,
                             std::string_view userPassword);

/** @brief sets user payload access data
 *
 *  @param[in] chNum - channel number
 *  @param[in] operation - ENABLE / DISABLE operation
 *  @param[in] userId - user id
 *  @param[in] payloadAccess - payload access data
 *
 *  @return ccSuccess for success, others for failure.
 */
Cc ipmiUserSetUserPayloadAccess(const uint8_t chNum, const uint8_t operation,
                                const uint8_t userId,
                                const PayloadAccess& payloadAccess);

/** @brief provides user payload access data
 *
 *  @param[in] chNum - channel number
 *  @param[in] userId - user id
 *  @param[out] payloadAccess - payload access data
 *
 *  @return ccSuccess for success, others for failure.
 */
Cc ipmiUserGetUserPayloadAccess(const uint8_t chNum, const uint8_t userId,
                                PayloadAccess& payloadAccess);

} // namespace ipmi
