#!/usr/bin/python
# -*- coding: UTF-8 -*-+
import pathlib
import os
import utils.common.log as logger
from utils.business.param_util import ParamUtil
from plugins.DistributedStorage.common.RestClient import StorageSSHClient
from plugins.DistributedStorage.common.constants import SERVICE_NAME


class UpgradeHotPatchOperate:
    @staticmethod
    def backup_db_data(ssh_client, remote_path, step="hotpatch"):
        err_msg = f"Backup {step} db data failed, Details:%s."
        cmd = "sh %s/backupDB.sh %s;echo last_result=$?" % (remote_path, step)
        try:
            cmd_res = ssh_client.send_cmd(cmd, "#", timeout=1200)
        except Exception as e:
            logger.error(err_msg % e)
            raise Exception(err_msg % e) from e
        if str(cmd_res).find("last_result=0") == -1:
            logger.error(err_msg % cmd_res)
            raise Exception(err_msg % cmd_res)

    @staticmethod
    def backup_repo_data(ssh_client, remote_path):
        err_msg = "Backup software repository failed, Details:%s."
        cmd = "sh %s/backupRepo.sh;echo last_result=$?" % remote_path
        try:
            cmd_res = ssh_client.send_cmd(cmd, "#", timeout=6000)
        except Exception as e:
            logger.error(err_msg % e)
            raise Exception(err_msg % e) from e
        if str(cmd_res).find("last_result=0") == -1:
            logger.error(err_msg % cmd_res)
            raise Exception(err_msg % cmd_res)

    @staticmethod
    def restore_db_data(remote_path, ssh_client, step="hotpatch"):
        """
        恢复存储大包数据库数据：只能在主节点上执行
        """
        logger.info("Restore DB data start.")
        err_msg = f"Restore {step} data failed, Details:%s."
        cmd = "sh %s/restoreDB.sh %s;echo last_result=$?" % (remote_path, step)
        try:
            cmd_res = ssh_client.send_cmd(cmd, "#", timeout=1200)
        except Exception as e:
            logger.error(err_msg % e)
            raise Exception(err_msg % e)
        if str(cmd_res).find("last_result=0") == -1:
            logger.error(err_msg % cmd_res)
            raise Exception(err_msg % cmd_res)
        logger.info("Restore DB data success.")

    @staticmethod
    def restore_repo_data(remote_path, ssh_client):
        """
        恢复存储软件：只能在主节点上执行
        """
        logger.info("Restore software repository start.")
        err_msg = "Restore software repository failed, Details:%s."
        cmd = "sh %s/restoreRepo.sh;echo last_result=$?" % remote_path
        try:
            cmd_res = ssh_client.send_cmd(cmd, "#", timeout=6000)
        except Exception as e:
            logger.error(err_msg % e)
            raise Exception(err_msg % e) from e
        if str(cmd_res).find("last_result=0") == -1:
            logger.error(err_msg % cmd_res)
            raise Exception(err_msg % cmd_res)
        logger.info("Restore software repository success.")

    @staticmethod
    def clear_backup_data(remote_path, ssh_client):
        logger.info("Clear host[%s] backup data start. " % ssh_client.host_ip)
        cmd = "sh %s/clearData.sh;echo last_result=$?" % remote_path
        err_msg = "Clear backup data failed, Details:%s."
        try:
            cmd_res = ssh_client.send_cmd(cmd, "#", timeout=6000)
        except Exception as e:
            logger.error(err_msg % e)
            raise Exception(err_msg % e) from e
        if str(cmd_res).find("last_result=0") == -1:
            logger.error(err_msg % cmd_res)
            raise Exception(err_msg % cmd_res)

    @staticmethod
    def upload_script_to_fsm(ssh_client, master_node, remote_path="/home/upgrade_tmp_hotpatch"):
        logger.info("Upload hotpatch script to fsm node[%s] start." % ssh_client.host_ip)
        script_path = pathlib.Path(pathlib.Path(__file__).resolve().parent.parent, "tool")
        file_name_list = ["backupDB.sh", "backupRepo.sh", "clearData.sh",
                          "restoreDB.sh", "restoreRepo.sh"]
        cmd_tmp = f"[ -d {remote_path} ] && rm -rf {remote_path}"
        ssh_client.send_cmd(cmd_tmp, "#")
        cmd_tmp = f'su {master_node.user_name} /bin/bash -c ' \
                  f'"mkdir -p {remote_path}; chmod 750 {remote_path}"'
        cmd_res = ssh_client.send_cmd(cmd_tmp, "#", 60, 3)
        logger.info("Make an directory on host[%s], result: %s" % (master_node.ip, cmd_res))
        for _file in file_name_list:
            local_file = os.path.join(str(script_path), _file)
            ssh_client.upload(local_file, remote_path)
            cmd_tmp = "dos2unix %s/%s" % (remote_path, _file)
            ssh_client.send_cmd(cmd_tmp, "#")

        logger.info("Upload hotpatch script to fsm node success.")

    @staticmethod
    def del_script_om_fsm(ssh_client, remote_path="/home/upgrade_tmp_hotpatch"):
        cmd_tmp = f"[ -d {remote_path} ] && rm -rf {remote_path}"
        ssh_client.send_cmd(cmd_tmp, "#")

    @staticmethod
    def get_master_node_client(node_info_list: list):
        """
        node_info_list:主备节点信息
        return: 主节点ssh client
                主节点node info
        """
        ssh_client = None
        node = None
        for node in node_info_list:
            ssh_client = StorageSSHClient(*node[:3])
            ssh_client.switch_root(node.root_pwd)

            ha_info_cmd = "/opt/dfv/oam/oam-u/ha/tools/getHAStatus.sh | grep LOCAL_ROLE " \
                          "| awk -F : '{print $2}'|awk '$1=$1'"
            cmd_ret = ssh_client.send_cmd(ha_info_cmd, '#')
            if "active\n" in cmd_ret:
                break
        if ssh_client is None:
            err_msg = "The primary fsm node is not found."
            logger.error(err_msg)
            raise Exception(err_msg)
        return ssh_client, node

    @staticmethod
    def init_operate_state(project_id, region_id, param_key):
        """
        初始化记录升级、回滚、确认工步执行步骤状态为初始值0
        """
        ParamUtil().set_service_cloud_param(
            project_id, SERVICE_NAME, region_id, param_key, 0)

    @staticmethod
    def get_operate_state(project_id, region_id, param_key):
        state = ParamUtil().get_value_from_cloud_param(
            project_id, SERVICE_NAME, param_key, region_id)
        return int(state)

    @staticmethod
    def update_operate_state(project_id, region_id, param_key, state=0):
        ParamUtil().set_service_cloud_param(
            project_id, SERVICE_NAME, region_id, param_key, state)

    @staticmethod
    def config_oam_u_firewall(ssh_client):
        """
        801升级至812后需要配置oam_u防火墙
        """
        cmd = "sh /opt/dfv/oam/public/script/upgrade_rollback/notify_finished/" \
              "FusionStorage_oam-u/nma.sh;echo last_result=$?"
        logger.info("Config oam_u firewall")
        err_msg = "Config oam_u firewall failed, Details:%s."
        try:
            cmd_res = ssh_client.send_cmd(cmd, "#", timeout=300)
        except Exception as e:
            logger.error(err_msg % e)
            raise Exception(err_msg % e) from e
        if str(cmd_res).find("last_result=0") == -1:
            logger.error(err_msg % cmd_res)
            raise Exception(err_msg % cmd_res)


