# -*- coding: utf-8 -*-
# Copyright (c) Huawei Technologies Co., Ltd. 2022-2023. All rights reserved.
import traceback
from utils.common.exception import FCDException
from utils.common.fic_base import TestCase
from utils.common.message import Message
import utils.common.log as logger
from plugins.DistributedStorage.scripts.logic.InstallOperate import InstallOperate
from plugins.DistributedStorage.scripts.logic.vm_operate import VMOperate
import plugins.DistributedStorage.scripts.utils.common.crypt_api as cryptApi


class InstallFSM(TestCase):
    def __init__(self, project_id, pod_id, fs_args, **kwargs):
        super(InstallFSM, self).__init__(project_id, pod_id)
        self.operate = InstallOperate(self.project_id, self.pod_id, fs_args)
        self.vm_operate = VMOperate(self.project_id, self.pod_id, fs_args)
        self.float_ip = fs_args.get("float_ip")
        self.master_fsm = dict()
        self.standby_fsm = dict()
        self.more_args = kwargs
        self.is_manage = fs_args.get("is_manage", False)

    def procedure(self):
        try:
            self.main()
        except FCDException as e:
            logger.error(traceback.format_exc())
            raise e
        except Exception as e:
            logger.error(traceback.format_exc())
            raise e

    def main(self):
        logger.info("Start to install FSM.")
        # 获取FSM虚拟机所在的节点
        logger.info("Query vm info for install FSM.")
        self.master_fsm, self.standby_fsm = self.vm_operate.get_vm_data(self.pod_id, self.float_ip)
        master_fsm_ip = self.master_fsm.get('om_ip')
        master_fsm_user = self.master_fsm.get('user')
        master_fsm_passwd = self.master_fsm.get('passwd')
        master_fsm_root_pwd = self.master_fsm.get('root_pwd')
        standby_fsm_ip = self.standby_fsm.get('om_ip')
        standby_fsm_user = self.standby_fsm.get('user')
        standby_fsm_passwd = self.standby_fsm.get('passwd')
        standby_fsm_root_pwd = self.standby_fsm.get('root_pwd')

        # 打开FSM root用户
        logger.info("Open root access.")
        self.operate.open_sys_root(master_fsm_ip, master_fsm_user, master_fsm_passwd, master_fsm_root_pwd)
        self.operate.open_sys_root(standby_fsm_ip, standby_fsm_user, standby_fsm_passwd, standby_fsm_root_pwd)

        self.general_ha_config_on_fsm_vm(master_fsm_ip, master_fsm_root_pwd,
                                         standby_fsm_ip, standby_fsm_root_pwd)

        # 2.上传安装包
        logger.info("Upload the fusionstorage installation package.")
        self.operate.upload_packet_to_host(master_fsm_ip, 'root', master_fsm_root_pwd)
        self.modify_resolve_file(master_fsm_ip, master_fsm_root_pwd,
                                 standby_fsm_ip, standby_fsm_root_pwd)
        # 3.执行FSM安装
        logger.info("Installing FSM")
        res = self.operate.install_fsm(master_fsm_ip, 'root', master_fsm_root_pwd)
        if 0 > str(res).find('last_cmd=0'):
            logger.error("Install FSM failed")
            master_err_detail = str(res).replace('\n', '')
            logger.error("Failed to install FSM.Detail:%s" % master_err_detail.replace('password', '******'))
            raise Exception("Failed to install FSM.Detail:%s" % master_err_detail)
        logger.info("Install FSM successful")

        self.close_os_first_login(master_fsm_ip, master_fsm_root_pwd,
                                  standby_fsm_ip, standby_fsm_root_pwd)

        # 关闭FSM root用户
        close_master_params = {'fsm_ip': master_fsm_ip,
                               'fsm_user': master_fsm_user,
                               'fsm_passwd': master_fsm_passwd,
                               'fsm_root_pwd': master_fsm_root_pwd}
        close_standby_params = {'fsm_ip': standby_fsm_ip,
                                'fsm_user': standby_fsm_user,
                                'fsm_passwd': standby_fsm_passwd,
                                'fsm_root_pwd': standby_fsm_root_pwd}
        self.operate.close_sys_root(close_master_params, True)
        self.operate.close_sys_root(close_standby_params, True)
        logger.info("Close root permision")

    def cleanup(self):
        logger.info("Start to clean up FSM VM nodes.")
        logger.info("Query newly created vm info for clean up.")
        # 获取FSM虚拟机所在的节点
        self.master_fsm, self.standby_fsm = self.vm_operate.get_vm_data(self.pod_id, self.float_ip)
        master_fsm_ip = self.master_fsm.get('om_ip')
        standby_fsm_ip = self.standby_fsm.get('om_ip')

        # 打开FSM root用户
        logger.info("Open root access.")
        self.operate.open_sys_root(master_fsm_ip, self.master_fsm.get('user'), self.master_fsm.get('passwd'),
                                   self.master_fsm.get('root_pwd'))
        self.operate.open_sys_root(standby_fsm_ip, self.standby_fsm.get('user'), self.standby_fsm.get('passwd'),
                                   self.standby_fsm.get('root_pwd'))
        if not self.is_manage:
            master_res = self.operate.unmodify_resolv_file(master_fsm_ip, 'root', self.master_fsm.get('root_pwd'))
            if 0 > str(master_res).find('last_cmd=0'):
                logger.error("unannotate /etc/resolv.conf file in master node failed,DetailL:%s" %
                             str(master_res).replace("\n", ''))
            standby_res = self.operate.unmodify_resolv_file(standby_fsm_ip, 'root', self.standby_fsm.get('root_pwd'))
            if 0 > str(standby_res).find('last_cmd=0'):
                logger.error("unannotate /etc/resolv.conf file  in standby node failed,DetailL:%s" %
                             str(master_res).replace("\n", ''))
        clr_fail_list = dict()
        logger.info("Start to clean up master FSM VM nodes[%s]." % master_fsm_ip)
        res = self.operate.clear_fsm(master_fsm_ip, 'root', self.master_fsm.get('root_pwd'))
        if 0 > str(res).find('last_cmd=0'):
            master_err_detail = res.replace('\n', '')
            clr_fail_list[master_fsm_ip] = master_err_detail
            logger.error("Failed to clean up FSM node[%s].Please clean it by manually.Detail:%s" % (
                master_fsm_ip, master_err_detail))

        logger.info("Start to clean up standby FSM VM nodes[%s]." % standby_fsm_ip)
        res = self.operate.clear_fsm(standby_fsm_ip, 'root', self.standby_fsm.get('root_pwd'))
        if 0 > str(res).find('last_cmd=0'):
            standby_err_detail = res.replace('\n', '')
            clr_fail_list[standby_fsm_ip] = standby_err_detail
            logger.error("Failed to clean up FSM node[%s]. Please clean it by manually.Detail:%s" % (
                standby_fsm_ip, standby_err_detail))

        if len(clr_fail_list.keys()) > 0:
            err_msg = "Failed to clean up nodes%s. Please clean it by manually. Detail:%s" % (
                list(clr_fail_list.keys()), clr_fail_list)
            logger.error(err_msg)
            raise Exception(err_msg)
        return Message()

    def general_ha_config_on_fsm_vm(self, master_fsm_ip, master_fsm_root_pwd,
                                    standby_fsm_ip, standby_fsm_root_pwd):
        """
        修改主备fsmHA配置文件
        :param master_fsm_ip:
        :param master_fsm_root_pwd:
        :param standby_fsm_ip:
        :param standby_fsm_root_pwd:
        :return:
        """
        # 获取FSM网络信息
        logger.info("Query network info.")
        self.master_fsm['netport'] = self.operate.get_netport_of_ip(master_fsm_ip, 'root', master_fsm_root_pwd)
        self.master_fsm['netmask'], self.master_fsm['gateway'] = self.operate.get_gateway_and_netmask_of_ip(
            master_fsm_ip, 'root', master_fsm_root_pwd, self.master_fsm.get('netport'))
        self.standby_fsm['gateway'] = self.master_fsm.get('gateway')
        self.standby_fsm['netmask'] = self.master_fsm.get('netmask')
        self.standby_fsm['netport'] = self.master_fsm.get('netport')

        logger.info("Generate Installation configuration files.")
        fsm_info = {'master_fsm': self.master_fsm,
                    'standby_fsm': self.standby_fsm}
        auto_key_b = cryptApi.gsecrtkey()
        if isinstance(auto_key_b, bytes):
            auto_key_b = auto_key_b.decode()
        account_set_cmd = self.operate.get_account_settings_cmd(auto_key_b)
        master_args = HAParams(*[master_fsm_ip, master_fsm_root_pwd, fsm_info, auto_key_b, account_set_cmd])
        standby_args = HAParams(*[standby_fsm_ip, standby_fsm_root_pwd, fsm_info, auto_key_b, account_set_cmd])
        master_ha_items = self.operate.get_master_ha_items(master_args)
        standby_ha_items = self.operate.get_standby_ha_items(standby_args)

        self.operate.general_ha_and_account_config(master_args, master_ha_items)
        self.operate.general_ha_and_account_config(standby_args, standby_ha_items)

    def close_os_first_login(self, master_fsm_ip, master_fsm_root_pwd,
                             standby_fsm_ip, standby_fsm_root_pwd):
        """
        设置虚拟机最后一次修改密码时间
        :param master_fsm_ip:
        :param master_fsm_root_pwd:
        :param standby_fsm_ip:
        :param standby_fsm_root_pwd:
        :return:
        """
        res = self.operate.close_os_first_login(master_fsm_ip, 'root', master_fsm_root_pwd, 'dsware')
        if 0 > str(res).find('last_cmd=0'):
            logger.error("Install FSM failed")
            master_err_detail = str(res).replace('\n', '')
            logger.error("Failed to close dsware first login."
                         "Detail:%s" % master_err_detail.replace('password', '******'))
            raise Exception("Failed to close first login FSM.Detail:%s" % master_err_detail)
        res = self.operate.close_os_first_login(standby_fsm_ip, 'root', standby_fsm_root_pwd, 'dsware')
        if 0 > str(res).find('last_cmd=0'):
            logger.error("Install FSM failed")
            master_err_detail = str(res).replace('\n', '')
            logger.error("Failed to close dsware first login."
                         "Detail:%s" % master_err_detail.replace('password', '******'))
            raise Exception("Failed to close first login.Detail:%s" % master_err_detail)

    def modify_resolve_file(self, master_fsm_ip, master_fsm_root_pwd,
                            standby_fsm_ip, standby_fsm_root_pwd):
        if not self.is_manage:
            # 注释掉两个FSM 虚拟机节点上 /etc/resolv.conf 的配置 避免rpm等命令执行慢
            master_res = self.operate.modify_resolv_file(master_fsm_ip, 'root', master_fsm_root_pwd)
            if 0 > str(master_res).find('last_cmd=0'):
                logger.error("annotate /etc/resolv.conf file in master node failed,DetailL:%s" %
                             str(master_res).replace("\n", ''))
            standby_res = self.operate.modify_resolv_file(standby_fsm_ip, 'root', standby_fsm_root_pwd)
            if 0 > str(standby_res).find('last_cmd=0'):
                logger.error("annotate /etc/resolv.conf file  in standby node failed,DetailL:%s" %
                             str(master_res).replace("\n", ''))


class HAParams:
    def __init__(self, *args):
        self.fsm_ip = args[0]
        self.fsm_root_pwd = args[1]
        self.fsm_info = args[2]
        self.auto_key_b = args[3]
        self.account_set_cmd = args[4]
