-- Copyright (c) 2024 Huawei Technologies Co., Ltd.
-- openUBMC is licensed under Mulan PSL v2.
-- You can use this software according to the terms and conditions of the Mulan PSL v2.
-- You may obtain a copy of Mulan PSL v2 at: http://license.coscl.org.cn/MulanPSL2
-- THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
-- EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
-- MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
-- See the Mulan PSL v2 for more details.
-- Test passwords:[Paswd@9001, Paswd@9005, Paswd@9006, Paswd9005, Paswd_9005, 9005@Paswd]
local lu = require 'luaunit'
local custom_msg = require 'messages.custom'
local base_msg = require 'messages.base'
local enum = require 'class.types.types'
local account_policy_collection = require 'domain.account_policy_collection'
local account_policy = require 'domain.account_policies.account_policy'
local manager_account = require 'domain.manager_account.manager_account'
local account_collection = require 'domain.account_collection'

--- 用户名合法，应该检查成功
function TestAccount:test_when_unsername_valid_should_check_success()
    local account_type = enum.AccountType.Local:value()
    lu.assertIsTrue(self.test_account_policy_collection:check_user_name(account_type, 'Administrator'))
    lu.assertIsTrue(self.test_account_policy_collection:check_user_name(account_type, string.rep('A', 16)))
    lu.assertIsTrue(self.test_account_policy_collection:check_user_name(account_type, 'A#dministrator'))
    lu.assertIsTrue(self.test_account_policy_collection:check_user_name(account_type, 'A+dministrator'))
    lu.assertIsTrue(self.test_account_policy_collection:check_user_name(account_type, 'A-dminis_trator'))
    lu.assertIsTrue(self.test_account_policy_collection:check_user_name(account_type, '.A..dministrator'))
    lu.assertIsTrue(self.test_account_policy_collection:check_user_name(account_type, '.A..d_123'))
    lu.assertIsTrue(self.test_account_policy_collection:check_user_name(account_type, '...!@#$^*()-=+_'))
    lu.assertIsTrue(self.test_account_policy_collection:check_user_name(account_type, '_={};[]?.'))
    lu.assertIsTrue(self.test_account_policy_collection:check_user_name(account_type, '[Admin]'))
    lu.assertIsTrue(self.test_account_policy_collection:check_user_name(account_type, 'Ad{mi}n'))
    lu.assertIsTrue(self.test_account_policy_collection:check_user_name(account_type, ']Adm;i]n'))
    lu.assertIsTrue(self.test_account_policy_collection:check_user_name(account_type, '.Admin..'))
    lu.assertIsTrue(self.test_account_policy_collection:check_user_name(account_type, '_dm=in?'))
    lu.assertIsTrue(self.test_account_policy_collection:check_user_name(account_type, '[[[Ad}}}min{{'))
    lu.assertIsTrue(self.test_account_policy_collection:check_user_name(account_type, '|.root|'))
    lu.assertIsTrue(self.test_account_policy_collection:check_user_name(account_type, 'adm|in+1#'))
    lu.assertIsTrue(self.test_account_policy_collection:check_user_name(account_type, 't1@#!~`$^*()-_+?'))
end

--- 用户名不合法，应该检查失败
function TestAccount:test_when_unsername_invalid_should_check_fail()
    local account_type = enum.AccountType.Local:value()
    lu.assertIsFalse(self.test_account_policy_collection:check_user_name(account_type, ''))
    lu.assertIsFalse(self.test_account_policy_collection:check_user_name(account_type, '.'))
    lu.assertIsFalse(self.test_account_policy_collection:check_user_name(account_type, '..'))
    lu.assertIsFalse(self.test_account_policy_collection:check_user_name(account_type, ' Administrator'))
    lu.assertIsFalse(self.test_account_policy_collection:check_user_name(account_type, string.rep('A', 17)))
    lu.assertIsFalse(self.test_account_policy_collection:check_user_name(account_type, 'A:dministrator'))
    lu.assertIsFalse(self.test_account_policy_collection:check_user_name(account_type, 'A<dministrator'))
    lu.assertIsFalse(self.test_account_policy_collection:check_user_name(account_type, 'A>dministrator'))
    lu.assertIsFalse(self.test_account_policy_collection:check_user_name(account_type, 'A&dministrator'))
    lu.assertIsFalse(self.test_account_policy_collection:check_user_name(account_type, 'A,dministrator'))
    lu.assertIsFalse(self.test_account_policy_collection:check_user_name(account_type, 'A"dministrator'))
    lu.assertIsFalse(self.test_account_policy_collection:check_user_name(account_type, 'A/dministrator'))
    lu.assertIsFalse(self.test_account_policy_collection:check_user_name(account_type, 'A\\dministrator'))
    lu.assertIsFalse(self.test_account_policy_collection:check_user_name(account_type, 'A%dministrator'))
    lu.assertIsFalse(self.test_account_policy_collection:check_user_name(account_type, 'A dministrator'))
    lu.assertIsFalse(self.test_account_policy_collection:check_user_name(account_type, '#Administrator'))
    lu.assertIsFalse(self.test_account_policy_collection:check_user_name(account_type, '+Administrator'))
    lu.assertIsFalse(self.test_account_policy_collection:check_user_name(account_type, '-Administrator'))
    lu.assertIsFalse(self.test_account_policy_collection:check_user_name(account_type, 'A“dministrator'))
    lu.assertIsFalse(self.test_account_policy_collection:check_user_name(account_type, 'Administrator\r'))
    lu.assertIsFalse(self.test_account_policy_collection:check_user_name(account_type, 'Administrator\n'))
    lu.assertIsFalse(self.test_account_policy_collection:check_user_name(account_type, 'Administrator\f'))
    lu.assertIsFalse(self.test_account_policy_collection:check_user_name(account_type, 'Administrator\r\n\f'))
    lu.assertIsFalse(self.test_account_policy_collection:check_user_name(account_type, 'Administrator\n\n'))
    lu.assertIsFalse(self.test_account_policy_collection:check_user_name(account_type, 'Administrator\f\f'))
end

--- 设置本地用户AllowedLoginInterface合法应成功
function TestAccount:test_set_allowed_login_interfaces_success()
    -- 登录接口num:Web:1, SNMP:2, IPMI:4, SSH:8, SFTP:16, Local:64, Redfish:128
    local account_type = enum.AccountType.Local:value()
    self.test_account_policy_collection:set_allowed_login_interfaces(account_type, 1)
    self.test_account_policy_collection:set_allowed_login_interfaces(account_type, 2)
    self.test_account_policy_collection:set_allowed_login_interfaces(account_type, 4)
    self.test_account_policy_collection:set_allowed_login_interfaces(account_type, 8)
    self.test_account_policy_collection:set_allowed_login_interfaces(account_type, 64)
    self.test_account_policy_collection:set_allowed_login_interfaces(account_type, 128)
    self.test_account_policy_collection:set_allowed_login_interfaces(account_type, 80)
    self.test_account_policy_collection:set_allowed_login_interfaces(account_type, 137)
    self.test_account_policy_collection:set_allowed_login_interfaces(account_type, 223)
end

--- 设置本地用户AllowedLoginInterface不合法应失败
function TestAccount:test_set_allowed_login_interfaces_invalid_should_failed()
    -- 本地用户禁止关闭所有登录接口/只开启SFTP接口
    local account_type = enum.AccountType.Local:value()
    lu.assertErrorMsgContains(custom_msg.ArrayPropertyInvalidItemMessage.Name, function ()
        self.test_account_policy_collection:set_allowed_login_interfaces(account_type, 0)
    end)
    lu.assertErrorMsgContains(custom_msg.ArrayPropertyInvalidItemMessage.Name, function ()
        self.test_account_policy_collection:set_allowed_login_interfaces(account_type, 16)
    end)
    -- 不支持的登录接口
    lu.assertErrorMsgContains(base_msg.PropertyValueNotInListMessage.Name, function ()
        self.test_account_policy_collection:set_allowed_login_interfaces(account_type, 32)
    end)
    lu.assertErrorMsgContains(base_msg.PropertyValueNotInListMessage.Name, function ()
        self.test_account_policy_collection:set_allowed_login_interfaces(account_type, 111)
    end)
end

--- 检查登录接口是否在AllowedLoginInterfaces内
function TestAccount:test_check_login_interface_is_allowed()
    -- 137:Web,SSH,Redfish
    local account_type = enum.AccountType.Local:value()
    self.test_account_policy_collection:set_allowed_login_interfaces(account_type, 137)
    lu.assertIsTrue(self.test_account_policy_collection:check_login_interface_is_allowed(account_type, 1))
    lu.assertIsTrue(self.test_account_policy_collection:check_login_interface_is_allowed(account_type, 8))
    lu.assertIsTrue(self.test_account_policy_collection:check_login_interface_is_allowed(account_type, 128))
    lu.assertIsTrue(self.test_account_policy_collection:check_login_interface_is_allowed(account_type, 9))
    lu.assertIsTrue(self.test_account_policy_collection:check_login_interface_is_allowed(account_type, 137))
    lu.assertIsFalse(self.test_account_policy_collection:check_login_interface_is_allowed(account_type, 4))
    lu.assertIsFalse(self.test_account_policy_collection:check_login_interface_is_allowed(account_type, 132))
    lu.assertIsFalse(self.test_account_policy_collection:check_login_interface_is_allowed(account_type, 16))
    lu.assertIsFalse(self.test_account_policy_collection:check_login_interface_is_allowed(account_type, 80))
    -- 恢复操作
    self.test_account_policy_collection:set_allowed_login_interfaces(account_type, 223)
end

--- 获取OEM用户Visible属性
function TestAccount:test_get_oem_account_visible()
    local account_type = enum.AccountType.OEM:value()
    local result = self.test_account_policy_collection:get_visible(account_type)
    lu.assertEquals(result, false)
end

--- 设置OEM用户Visible属性
function TestAccount:test_set_oem_account_visible()
    local account_type = enum.AccountType.OEM:value()
    self.test_account_policy_collection:set_visible(self.ctx, account_type, true)
    local result = self.test_account_policy_collection:get_visible(account_type)
    lu.assertEquals(result, true)
    --恢复环境
    self.test_account_policy_collection:set_visible(self.ctx, account_type, false)
end

--- 获取OEM用户Deletable属性
function TestAccount:test_get_oem_account_deletable()
    local account_type = enum.AccountType.OEM:value()
    local result = self.test_account_policy_collection:get_deletable(account_type)
    lu.assertEquals(result, false)
end

--- 设置OEM用户Deletable属性
function TestAccount:test_set_oem_account_deletable()
    local account_type = enum.AccountType.OEM:value()
    self.test_account_policy_collection:set_deletable(self.ctx, account_type, true)
    local result = self.test_account_policy_collection:get_deletable(account_type)
    lu.assertEquals(result, true)
    --恢复环境
    self.test_account_policy_collection:set_deletable(self.ctx, account_type, false)
end

--- 获取Local用户online_deletable属性
function TestAccount:test_get_local_account_online_deletable()
    local account_type = enum.AccountType.Local:value()
    account_policy_collection.collection = {
        [0] = {
            get_online_deletable = nil
        }
    }
    local ok, _ = pcall(function ()
        account_policy_collection:get_online_deletable(account_type)
    end)
    lu.assertEquals(ok, false)
    account_policy_collection.collection = {
        [0] = {
            get_online_deletable = function ()
                return true
            end,
            set_online_deletable = function (value)
                return true
            end
        }
    }
    local ok, _ = pcall(function ()
        account_policy_collection:get_online_deletable(account_type)
    end)
    lu.assertEquals(ok, true)
end

--- 获取Local用户set online_deletable属性
function TestAccount:test_set_local_account_online_deletable()
    account_policy_collection.collection = {
        [0] = {
            get_online_deletable = function ()
                return true
            end,
            set_online_deletable = function (value)
                return true
            end
        }
    }
    account_policy_collection.m_config_changed = {
        emit = function(account_type, method, value)
        end
    }
    local account_type = enum.AccountType.Local:value()
    local ok, _ = pcall(function ()
        account_policy_collection:set_online_deletable(account_type, 1)
    end)
    lu.assertEquals(ok, true)
end

function TestAccount:test_account_policy_set_online_deletable()
    account_policy.data = {OnlineDeletable = true}
    local ok, _ = pcall(function ()
        account_policy:get_online_deletable(1)
    end)
    lu.assertEquals(ok, true)

    local ok, _ = pcall(function ()
        account_policy:set_online_deletable(1)
    end)
    lu.assertEquals(ok, true)
end

function TestAccount:test_manager_account_get_is_online()
    manager_account.m_account_data = {
        IsOnline = true,
        save = function()
        end
    }
    local ok, _ = pcall(function ()
        manager_account:get_is_online()
    end)
    lu.assertEquals(ok, true)

    local ok, _ = pcall(function ()
        manager_account:set_is_online(1)
    end)
    lu.assertEquals(ok, true)
end

function TestAccount:test_account_collection_set_is_online_change_required()
    account_collection.collection = {
        [1] = nil
    }
    local ok, _ = pcall(function ()
        account_collection:set_is_online_change_required(1, 1)
    end)
    lu.assertEquals(ok, false)
    account_collection.collection = {
        [1] = {
            set_is_online = function ()
            end
        }
    }
    local ok, _ = pcall(function ()
        account_collection:set_is_online_change_required(1, 1)
    end)
    lu.assertEquals(ok, true)
end