# -*- coding:utf-8 -*-
import os
import stat
from utils.common.fic_base import StepBaseInterface
from utils.common.message import Message
import utils.common.log as logger
from plugins.eBackup.common.util import get_ebackup_driver_nodes
from utils.common.exception import FCUException
from utils.DBAdapter.DBConnector import BaseOps
from utils.common.ssh_util import Ssh
from plugins.eBackup.common.util import Utils
from plugins.eBackup.common.params_check_tool import check_ssh_login
from platforms.upgradecheck.check_result import CheckResult
eBackup_Driver_status_check_SUCCESS = [
    CheckResult(itemname_ch="校验eBackup Driver节点fsp用户登录密码",
                itemname_en="Check the fsp user password of the eBackup "
                            "Driver nodes", status="success"),
    CheckResult(itemname_ch="检查即将过期的fsp用户登录密码",
                itemname_en="Check the fsp user password which is about"
                            " to expire", status="success"),
    CheckResult(itemname_ch="校验eBackup Driver节点root用户登录密码",
                itemname_en="Check the root user password of the eBackup "
                            "Driver nodes", status="success")
]


class DriverPrecheck(StepBaseInterface):
    def __init__(self, project_id, pod_id, regionid_list=None):
        super(DriverPrecheck, self).__init__(project_id, pod_id, regionid_list)
        self.project_id = project_id
        self.pod_id = pod_id
        self.regionid_list = regionid_list
        self.region_id = regionid_list[0]
        self.params_dict = Utils.init_system_params(project_id,
                                                    regionid_list[0])
        self.__ssh = Ssh()
        self.region_type = BaseOps().get_region_type(project_id).lower()

    def write_driver_node_to_file(self, driver_host_dict):
        try:
            logger.info("Begin to write driver nodes to file.")
            reverse_proxy_ip = self.params_dict["openstack_reverse_proxy_ip"]
            file_postfix = '.txt'
            file_path_name = os.path.realpath(
                __file__ + '/../' + '%s' + '_' + '%s' + '%s') % \
                (self.region_id, reverse_proxy_ip, file_postfix)
            flags = os.O_WRONLY | os.O_CREAT
            modes = stat.S_IWUSR | stat.S_IRUSR
            with os.fdopen(os.open(file_path_name, flags, modes), 'w') as fp:
                fp.truncate()
                # write cps node to file
                fp.write(','.join(driver_host_dict["cpsnode"]) + '\n')
                # write driver node to file
                fp.write(','.join(driver_host_dict["eBackupDriver"]) + '\n')
            logger.info("Wite driver nodes to [%s] successfully." %
                        file_path_name)
        except Exception as ex:
            logger.error(str(ex))
            raise ex

    def execute(self, project_id, pod_id, regionid_list=None):
        try:
            logger.info("The network type is %s" % self.region_type)
            all_driver_nodes = {
                "eBackupDriver": [],
                "cpsnode": []
            }
            cascading_reverse_ip = \
                self.params_dict["openstack_reverse_proxy_ip"]
            logger.info("Begin to query eBackup driver in cascading "
                        "layer " + cascading_reverse_ip)
            driver_hosts = get_ebackup_driver_nodes(cascading_reverse_ip,
                                                    self.params_dict)
            if 'cpsnode' in driver_hosts and 'eBackupDriver' in driver_hosts:
                all_driver_nodes["cpsnode"] = driver_hosts["cpsnode"]
                all_driver_nodes["eBackupDriver"] = \
                    driver_hosts["eBackupDriver"]
                logger.info("Cps server nodes in cascading layer "
                            "ares:" + str(all_driver_nodes["cpsnode"]))
                logger.info("Driver nodes in cascading layer "
                            "ares:" + str(all_driver_nodes["eBackupDriver"]))

            all_need_check_ips = all_driver_nodes["eBackupDriver"]
            [all_need_check_ips.append(ip) for ip in
                all_driver_nodes["cpsnode"] if ip not in all_need_check_ips]
            unpassed_fsp_nodes = []
            unpassed_root_nodes = []
            password_goto_expire_msg = {}
            for ip in all_need_check_ips:
                ret_code, msg = check_ssh_login(
                    ip, "fsp",
                    self.params_dict["openstack_fsp_pwd"],
                    self.params_dict["openstack_root_pwd"], 3)
                if 1 == ret_code:
                    unpassed_fsp_nodes.append(ip)
                elif 2 == ret_code:
                    unpassed_fsp_nodes.append(ip)
                elif 3 == ret_code:
                    password_goto_expire_msg.update(
                        {ip: "The fsp password will expire in %s days." % msg})
                elif 4 == ret_code:
                    unpassed_root_nodes.append(ip)

            check_result = []
            check_result_flag = True

            if 0 != len(password_goto_expire_msg):
                unpassed_ips = list(password_goto_expire_msg.keys())
                result = CheckResult(
                    itemname_ch="检查即将过期的fsp用户登录密码",
                    itemname_en="Check the fsp user password "
                                "which is about to expire",
                    status="failure",
                    error_msg_cn=FCUException(
                        650037, ','.join(unpassed_ips), 'fsp',
                        str(password_goto_expire_msg)))
                check_result_flag = False
            else:
                result = CheckResult(
                    itemname_ch="检查即将过期的fsp用户登录密码",
                    itemname_en="Check the fsp user "
                                "password which is about to expire",
                    status="success")
            check_result.append(result)
            if 0 != len(unpassed_fsp_nodes):
                result = CheckResult(
                    itemname_ch="校验eBackup Driver节点fsp用户登录密码",
                    itemname_en="Check the fsp user password of the"
                                " eBackup Driver nodes",
                    status="failure",
                    error_msg_cn=FCUException(
                        650005, ",".join(unpassed_fsp_nodes)))
                check_result_flag = False
            else:
                result = CheckResult(
                    itemname_ch="校验eBackup Driver节点fsp用户登录密码",
                    itemname_en="Check the fsp user password of "
                                "the eBackup Driver nodes",
                    status="success")
            check_result.append(result)
            if 0 != len(unpassed_root_nodes):
                result = CheckResult(
                    itemname_ch="校验eBackup Driver节点root用户登录密码",
                    itemname_en="Check the root user password "
                                "of the eBackup Driver nodes",
                    status="failure",
                    error_msg_cn=FCUException(650006,
                                              ','.join(unpassed_root_nodes)))
                check_result_flag = False
            else:
                result = CheckResult(
                    itemname_ch="校验eBackup Driver节点root用户登录密码",
                    itemname_en="Check the root user password"
                                " of the eBackup Driver nodes",
                    status="success")
            check_result.append(result)
            if check_result_flag:
                self.write_driver_node_to_file(all_driver_nodes)
                logger.info("Check password successfully and write nodes to "
                            "file successfully.")
            else:
                logger.error("Check password failed,it is no need to "
                             "write nodes to file.")
            return Message(200, check_results=check_result)
        except FCUException as e:
            logger.error("Precheck driver failed: " + str(e))
            return Message(500, e)
        except Exception as e:
            logger.error("Failed to precheck eBackup Driver,the "
                         "reason is %s" % e)
            return Message(
                500, error_msg_cn="升级前检查出现异常，请查看日志并重"
                                  "试，异常信息:%s" % str(e),
                error_msg_en="Exception occurs while prechecking,"
                             "please check the log and try again,"
                             " error info:%s." % str(e))

    def rollback(self, project_id, pod_id, regionid_list=None):
        return Message(200)

    def retry(self, project_id, pod_id, regionid_list=None):
        return self.execute(project_id, pod_id, regionid_list)
