# -*- coding: utf-8 -*-
# Copyright (c) Huawei Technologies Co., Ltd. 2022-2023. All rights reserved.
import time
import datetime
import traceback
from copy import deepcopy

import utils.common.log as logger
from utils.common.fic_base import TestCase
from utils.common.message import Message
from utils.business.param_util import ParamUtil
from utils.business.manageone_util2 import ManageOneUtil2
from plugins.DistributedStorage.scripts.logic.vm_operate import VMOperate


class RegAccountToUnifyPwd(TestCase):
    def __init__(self, project_id, pod_id, fs_args):
        super().__init__(project_id, pod_id)
        self.fs_args = fs_args
        self.vm_flag = self.fs_args.get('vm_boolean')
        self.osd_flag = self.fs_args.get('osd_boolean')
        self.rep_flag = self.fs_args.get('replication_boolean')
        self.manage_one_opr = ManageOneUtil2()
        self.vm_operate = VMOperate(self.project_id, self.pod_id, self.fs_args)
        self.region_id = ParamUtil().get_param_value(self.pod_id, '', '', 'region0_id')
        self.sub_component_name = 'Distributed Block Storage'

    @staticmethod
    def get_account_info(account_info):
        """
        组装待注册账户登录信息
        """
        general_account_info = {'ip_value': account_info.get('om_ip'),
                                'user': account_info.get('user'),
                                'pwd': account_info.get('passwd')}
        root_account_info = {'ip_value': account_info.get('om_ip'),
                             'user': 'root',
                             'pwd': account_info.get('root_pwd')}
        return [general_account_info, root_account_info]

    def procedure(self):
        """
        针对管理融合、业务分离、业务融合，以及扩容场景：获取待注册账号信息 -> 组装账户唯一标识信息 -> 调用uniform_password_util注册

        部署工程、扩AZ kvm新建，self.vm_flag == True
        扩云服务、新增业务存储、扩AZ(kvm/BMS)复用、扩业务计算融合部署场景不创虚拟机，self.vm_flag == False
        """
        try:
            self.main()
        except Exception as e:
            logger.error(traceback.format_exc())
            return Message(500, e)
        return Message(200)

    def main(self):
        logger.info('Query register nodes info')
        reg_accounts_info = self.get_account_data()
        logger.info('Query nodes info successfully')
        if reg_accounts_info:
            logger.info('Registering account to manage one')
            for account in reg_accounts_info:
                logger.info('Registering account to manage one: {}'.format(account))
                self.reg_account_to_unify_pwd(account)
                logger.info('The account is registered successfully: [ip:{}, account:{}]'
                            .format(account.get('ip_value'), account.get('user')))
        logger.info('All accounts are registered successfully')

    def get_account_data(self):
        """
        获取待注册账户信息
        """
        account_list = list()
        if self.vm_flag:
            float_ip = self.fs_args.get("float_ip")
            logger.info('Query vm info')
            master_fsm_info, standby_fsm_info = self.vm_operate.get_vm_data(self.pod_id, float_ip)
            logger.info('Query vm info successfully')
            account_list.extend(self.get_account_info(master_fsm_info))
            account_list.extend(self.get_account_info(standby_fsm_info))
        osd_info_list = self.fs_args.get('osd_list')
        if osd_info_list and self.osd_flag:
            for osd_info in osd_info_list:
                account_list.extend(self.get_account_info(osd_info))
        rep_info_list = self.fs_args.get('vbs_list')
        if rep_info_list and self.rep_flag:
            for rep_info in rep_info_list:
                account_list.extend(self.get_account_info(rep_info))
        return account_list

    def reg_account_to_unify_pwd(self, account_info):
        """
        组装统一密码唯一标识信息，并注册

        subComponentName示例: az0.dc0 Manage Converged Storage
        """
        ip_value, user, pwd = account_info.get('ip_value'), account_info.get('user'), account_info.get('pwd')
        now_time = int(round(time.time() * 1000))
        expire_time = now_time + 90 * 24 * 3600 * 1000
        body = self.get_body_dic(user, ip_value, pwd, expire_time)
        if user == 'root':
            try:
                body["subComponents"][0]["createdAccountList"][0]["passwdComplexity"][
                    "passwdChangeMaxBetweenTime"] = 99999
            except KeyError as e:
                logger.error('Key not exist. Detail:%s' % str(e))
                raise e
            try:
                body["subComponents"][0]["createdAccountList"][0]["passwdExpires"] = -1
            except KeyError as e:
                logger.error('Key not exist. Detail:%s' % str(e))
                raise e
            try:
                body["subComponents"][0]["createdAccountList"][0]["accountDescription"] = \
                    "{\"zh-cn\":\"操作系统管理员，用于登录虚拟机的操作系统，可以执行所有命令。考虑到对系统安全的影响，在登录节点时，" \
                    "不能使用root帐号直接登录，需要使用普通帐号登录后通过执行命令su root切换为root帐号\",\"en-us\":\"The operating " \
                    "system administrator is used to log in to the operating system of the virtual machine and can " \
                    "execute all commands. Considering the impact on system security,When logging in to a node," \
                    " you cannot use the root account to log in directly. You need to log in with a normal account " \
                    "and switch to the root account by executing the command su root.\"}"
            except KeyError as e:
                logger.error('Key not exist. Detail:%s' % str(e))
                raise e
            try:
                body["subComponents"][0]["createdAccountList"][0]["riskMessage"] = \
                    "{\"zh-cn\":\"密码不会过期，修改密码对业务暂无影响\",\"en-us\":\"The password will not expire, " \
                    "and changing the password has no impact on the business temporarily.\"}"
            except KeyError as e:
                logger.error('Key not exist. Detail:%s' % str(e))
                raise e
        body_tmp = deepcopy(body)
        try:
            body_tmp["subComponents"][0]["createdAccountList"][0]['passwd'] = '***'
        except KeyError as e:
            err_msg = 'Key not exist. Detail:%s' % str(e)
            logger.error(err_msg)
            raise e
        logger.info('body:{}'.format(body_tmp))

        logger.info('starting to register account by interface')
        self.manage_one_opr.uniform_password_util(self.project_id, self.pod_id, body)

    def get_body_dic(self, user, ip_value, pwd, expire_time):
        body = {
            "componentName": 'Distributed storage',
            "ruleList": [],
            "subComponents": [
                {
                    "createdAccountList": [
                        {
                            "accountDescription": "{\"zh-cn\":\"登录账号\",\"en-us\":\"logion administrator account\"}",
                            "accountName": user,
                            "accountType": 1,
                            "lastPasswdChange": int(round(datetime.datetime.utcnow().timestamp() * 1000)),
                            # 获取系统当前UTC时间戳
                            "modifyType": 2,
                            "operationType": 0,
                            "ip": ip_value,
                            "passwd": pwd,
                            "passwdComplexity": {
                                "dcredit": 0,
                                "difok": 3,
                                "lcredit": 0,
                                "minlen": 8,
                                "ocredit": 0,
                                "passwdChangeMaxBetweenTime": 90,
                                "passwdChangeMinBetweenTime": 0,
                                "ucredit": 0
                            },
                            "passwdExpires": expire_time,
                            "region": self.region_id,
                            "relativeAccount": [],
                            "riskMessage": "{\"zh-cn\":\"此账号用户密码会过期，过期时间默认90天，请注意在过期时间前修改密码，"
                                           "否则无法登陆\",\"en-us\":\"This user’s password will expire, and the "
                                           "expiration time is 90 days by default. Please note that you can change "
                                           "the password before the expiration time, otherwise you cannot log in.\"}",
                            "usedScene": "Distributed storage"
                        }
                    ],
                    "subComponentName": self.sub_component_name,
                    "usedAccountList": []
                }
            ]
        }
        return body
