# -*- coding:utf-8 -*-
import os
import utils.common.log as logger
from plugins.eBackup.common.dmkTask import DMKTask
from plugins.eBackup.common.util import DriverConfig
from utils.common.ssh_util import Ssh
from plugins.eBackup.common.util import Utils
from plugins.eBackup.common.util import get_ebackup_driver_nodes_from_file


class EbackupDriverUpgrader(object):
    def __init__(self, reverse_proxy_ip, param_dict):
        self.reverse_proxy_ip = reverse_proxy_ip
        self.param_dict = param_dict
        self.dmk_task = DMKTask(param_dict['dmk_floatIp'],
                                param_dict['eBackup_dmk_user'],
                                param_dict['eBackup_dmk_password'])
        self.hosts_dict = self._get_host_dict(reverse_proxy_ip)

    def upgrade(self):
        if 0 == len(self.hosts_dict):
            logger.info("eBackup is not supported in cascaded layer:" + self.
                        reverse_proxy_ip)
            return True
        is_true = self.is_all_upgraded()
        if is_true:
            logger.info("All nodes are upgraded.")
            return True
        return self.deploy_with_dmk("upgrade")

    def rollback(self):
        if 0 == len(self.hosts_dict):
            logger.info("eBackup is not supported in cascaded layer:" + self.
                        reverse_proxy_ip)
            return True
        is_true = self.is_all_rollbacked()
        if is_true:
            logger.info("All nodes are rollbacked.")
            return True
        return self.deploy_with_dmk("rollback")

    def _get_host_dict(self, reverse_proxy_ip):
        region_id = self.param_dict["current_region_id"]
        file_path = os.path.realpath(
            __file__ + '/../' + region_id + '_' + reverse_proxy_ip + '.txt')
        driver_host_dict = get_ebackup_driver_nodes_from_file(file_path)
        if 0 == len(driver_host_dict):
            logger.info(
                "eBackup is not supported in cascaded"
                " layer:" + reverse_proxy_ip)
            return {}
        return driver_host_dict

    def is_all_upgraded(self):
        logger.info("Begin to check whether all node are upgraded.")
        for ip in self.hosts_dict['eBackupDriver']:
            if not self.is_upgraded(ip):
                logger.info("There some nodes are not upgraded.")
                return False
        logger.info("All nodes are upgraded.")
        return True

    def is_all_rollbacked(self):
        logger.info("Begin to check whether all node are rollbacked.")
        for ip in self.hosts_dict['eBackupDriver']:
            if self.is_upgraded(ip):
                logger.info("There some nodes are not rollbacked.")
                return False
        logger.info("All nodes are rollbacked.")
        return True

    def is_upgraded(self, ip):
        ssh = Ssh()
        ssh_client = None
        logger.info("Begin to check current version at host %s" % ip)
        if self.param_dict['update_scene'] == 'upgrade':
            version_check_cmds = '''version_info=$(cat /usr/lib/python2.7''' \
                                 '''/site-packages/cinder/backup/drivers/''' \
                                 '''ebackupversion.conf 2>/dev/null || ''' \
                                 '''cat /opt/cloud/services/cascading-''' \
                                 '''cinder/venv/lib/python2.7/site-package''' \
                                 '''s/cinder/backup/drivers/ebackupversi''' \
                                 '''on.conf 2>/dev/null || ''' \
                                 '''cat /usr/lib64/python2.7/site-package''' \
                                 '''s/cinder/backup/drivers/ebackupversio''' \
                                 '''n.conf 2>/dev/null);''' \
                                 '''echo ${version_info} | awk -''' \
                                 '''F "[=| ]" '{print $2}' '''

        else:
            version_check_cmds = '''version_info=$(grep -r "Version:"/usr/''' \
                                 '''lib/python2.7/site-packages/cinder/''' \
                                 '''backup/ebackup_driver_backup/ 2>''' \
                                 '''/dev/null || ''' + \
                                 '''grep -r "Version:" /opt/cloud/services''' \
                                 '''/cascading-cinder/venv/lib/python2.7/''' \
                                 '''site-packages/cinder \n/backup/ebackup''' \
                                 '''_driver_backup/ 2>/dev/null || ''' + \
                                 '''grep -r "Version:" /usr/lib64/python''' \
                                 '''2.7/site-packages/cinder/backup/''' \
                                 '''ebackup_driver_backup/ 2>/dev/null);''' + \
                                 '''echo ${version_info} | grep -w %s | ''' \
                                 '''awk -F "[ |:]" '{print $NF}' ''' % \
                                 self.param_dict['eBackup_Version']
        try:
            ssh_client = ssh.ssh_create_client(
                ip, 'fsp', self.param_dict['openstack_fsp_pwd']
            )
            ssh.ssh_send_command(ssh_client, 'su - root', 'Password:', 100)
            ssh.ssh_send_command(
                ssh_client, self.param_dict['openstack_root_pwd'], '#', 100
            )
            result = ssh.ssh_exec_command_return_list(ssh_client,
                                                      version_check_cmds)
            current_version = "No patch" if len(result) == 0 else \
                result[0].strip().replace('\n', '')
            logger.info("The current version is %s at host %s" %
                        (current_version, ip))
            return current_version == self.param_dict['eBackup_Version']
        except Exception as e:
            logger.error("Exception occurs when check current version,the"
                         " Exception is:" + str(e))
            raise e
        finally:
            Utils.close_ssh_clinet(ssh_client)

    def deploy_with_dmk(self, action):
        ebackup_driver_config, ebackup_driver_host = self.get_all_params()

        # install eBackup
        ebackup_action = ""
        if action == "upgrade":
            ebackup_action = "[upgrade]3.Upgrade eBackup Driver" if \
                self.param_dict['update_scene'] == 'upgrade' \
                else '[Upgrade] Upgrade eBackup Driver Patch'
        elif action == "rollback":
            ebackup_action = "[rollback]2.Rollback eBackup Driver" if \
                self.param_dict['update_scene'] == 'upgrade' \
                else '[Rollback] Rollback eBackup Driver Patch'
        application = 'eBackup_Upgrade' if \
            self.param_dict['update_scene'] == 'upgrade' \
            else 'eBackupSoftware_Patch'

        result = self.dmk_task.do_task(self.param_dict["eBackup_Version"],
                                       ebackup_action,
                                       ebackup_driver_host,
                                       ebackup_driver_config, "fsp",
                                       application)

        if not result:
            logger.error("Do DMK task %s failed." % ebackup_action)
        return result

    def get_all_params(self):
        config = DriverConfig(hosts_dict=self.hosts_dict,
                              param_dict=self.param_dict, one2all=0)
        return config.get_config()
