# -*- coding:utf-8 -*-
import os
from utils.common.fic_base import StepBaseInterface
from utils.common.message import Message
import utils.common.log as logger
from utils.DBAdapter.DBConnector import BaseOps
from plugins.eBackup.common.util import get_cascaded_reverse_ips, get_ebackup_driver_nodes_from_file
from plugins.eBackup.common.eBackupUpgrade import eBackupUpgrader
from plugins.eBackup.common.eBackupDriverUpgrade import eBackupDriverUpgrader
from utils.common.ssh_util import Ssh
from plugins.eBackup.common.util import Utils

class DatamoverRollback(StepBaseInterface):
    def __init__(self, project_id, pod_id, regionid_list):
        super(DatamoverRollback, self).__init__(project_id, pod_id, regionid_list)
        self.project_id = project_id
        self.pod_id = pod_id
        self.regionid_list = regionid_list
        self.__db_param_dict = Utils.init_system_params(project_id, regionid_list[0])

    def pre_check(self, project_id, pod_id, regionid_list):
        pass

    def execute(self, project_id, pod_id, regionid_list):
        try:
            host_info = self.__db_param_dict["eBackup_Datamover_nodes"]
            host_info = host_info.replace(" ", "").split("|")


            all_result = []
            logger.info("Begin to rollback all datamover nodes(%s)" % str(host_info))
            for host_ips in host_info:
                host_ips = host_ips.split(";")
                logger.info("Begin to rollback datamover nodes(%s)" % str(host_ips))
                ebckup_upgrade = eBackupUpgrader(host_ips, self.__db_param_dict, "datamover")
                is_true = ebckup_upgrade.rollback()
                if not is_true:
                    logger.error("Rollback datamover nodes(%s) failed." % str(host_ips))
                else:
                    logger.info("Rollback datamover nodes(%s) successfully." % str(host_ips))
                all_result.append(is_true)

            if False in all_result:
                logger.error("Rollback all datamover nodes failed.")
                return Message(500, error_msg_cn="回退Datamover失败，请登录DMK查看失败原因，请勿直接重试",
                               error_msg_en="Rollback Datamover failed, please log in DMK to see the details, do not directly retry")

            logger.info("Rollback all datamover nodes successfully.")
            return Message(200)
        except Exception as e:
            logger.error("Failed to rollback datamover ,the reason is %s" % e)
            return Message(500, str(e), str(e))

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

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

class WorkflowRollback(StepBaseInterface):
    def __init__(self, project_id, pod_id, regionid_list):
        super(WorkflowRollback, self).__init__(project_id, pod_id, regionid_list)
        self.project_id = project_id
        self.pod_id = pod_id
        self.regionid_list = regionid_list
        self.__db_param_dict = Utils.init_system_params(project_id, regionid_list[0])

    def pre_check(self, project_id, pod_id, regionid_list):
        pass

    def execute(self, project_id, pod_id, regionid_list):
        try:
            host_info = self.__db_param_dict['eBackup_Workflow_nodes']
            host_info = host_info.replace(" ", "").split("|")

            all_result = []
            logger.info("Begin to rollback all workflow nodes(%s)" % str(host_info))
            for host_ips in host_info:
                host_ips = host_ips.split(";")
                logger.info("Begin to rollback workflow nodes(%s)" % str(host_ips))
                ebckup_upgrade = eBackupUpgrader(host_ips, self.__db_param_dict, "workflow")
                is_true = ebckup_upgrade.rollback()
                if not is_true:
                    logger.error("Fail to rollback workflow nodes(%s)" % str(host_ips))
                else:
                    logger.info("Rollback workflow nodes(%s) successfully." % str(host_ips))
                all_result.append(is_true)

            if False in all_result:
                logger.error("Fail to rollback all workflow nodes.")
                return Message(500, error_msg_cn="回退Workflow失败，请登录DMK查看失败原因，请勿直接重试",
                               error_msg_en="Rollback Workflow failed, please log in DMK to see the details, do not directly retry")

            logger.info("Rollback all datamover nodes successfully.")
            return Message(200)

        except Exception as e:
            logger.error("Failed to rollback workflow ,the reason is %s" % e)
            return Message(500, str(e), str(e))

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

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


class DriverRollback(StepBaseInterface):
    def __init__(self, project_id, pod_id, regionid_list):
        super(DriverRollback, 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.database = BaseOps()
        self.__db_param_dict = Utils.init_system_params(project_id, regionid_list[0])
        self.__ssh = Ssh()

    def pre_check(self, project_id, pod_id, regionid_list):
        return Message(200)


    def _execute_rollback(self, reverse_proxy_ip):
        try:
            driver_upgrade = eBackupDriverUpgrader(reverse_proxy_ip, self.__db_param_dict)
            rollback_result = driver_upgrade.rollback()
            return rollback_result
        except Exception as ex:
            logger.error("Exception occurs:" + str(ex))
            return False

    def execute(self, project_id, pod_id, regionid_list):
        region_type = self.database.get_region_type(self.project_id)
        logger.info("The network type is %s" % region_type)
        if region_type == "Type1":
            try:
                cascaded_reverse_ips = get_cascaded_reverse_ips(self.__db_param_dict)
                if 0 == len(cascaded_reverse_ips):
                    logger.error("Fail to get reverse proxy ips of the cascaded layers.")
                    raise Exception("Fail to get reverse proxy ips of the cascaded layers.")

                all_cascaded_result = []
                for each_reverse_ip in cascaded_reverse_ips:
                    is_true = self._execute_rollback(each_reverse_ip)
                    if is_true:
                        logger.info("Rollback eBackup driver successfully "
                                    "in the cascaded layer(%s)" % each_reverse_ip)
                    else:
                        logger.error("Fail to rollback eBackup driver "
                                     "in the cascaded layer(%s)" % each_reverse_ip)
                    all_cascaded_result.append(is_true)
                if False in all_cascaded_result:
                    logger.error("Fail to rollback eBackup driver in the all cascaded layer")
                    return Message(500, "Fail to rollback all cascaded layer")
                return Message(200)

            except Exception as ex:
                logger.error(str(ex))
                return Message(500, str(ex), str(ex))
        else:
            try:
                reverse_proxy_ip = self.__db_param_dict['openstack_reverse_proxy_ip']
                if reverse_proxy_ip is None:
                    logger.info("openstack_reverse_proxy_ip is None,eBackup driver rollback skipped...")
                    return Message(200)
                is_true = self._execute_rollback(reverse_proxy_ip)
                if not is_true:
                    logger.info("Fail to Upgrade eBackup driver.")
                    return Message(500, "Fail to Upgrade eBackup driver.")
                return Message(200)

            except Exception as ex:
                logger.error(str(ex))
                return Message(500, str(ex), str(ex))

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

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