# -*- coding: utf-8 -*-
import traceback
from utils.common.fic_base import TestCase
import utils.common.log as logger
from utils.common.message import Message
from utils.common.exception import HCCIException
from utils.common.ssh_util import Ssh as ssh
from utils.business.hardware_driver_util import DriverApi
from plugins.DistributedStorage.utils.common.DeployConstant import DeployConstant
from plugins.DistributedStorage.logic.InstallOperate import InstallOperate, InstallDriverOperate


class InstallDriver(TestCase):
    def __init__(self, project_id, pod_id, fs_args, condition=None, metadata=None, **kwargs):
        super(InstallDriver, self).__init__(project_id, pod_id)
        self.condition = condition
        self.metadata = metadata
        self.more_args = kwargs
        self.osd_list = fs_args.get('osd_list')
        self.operate = InstallOperate(self.project_id, self.pod_id, fs_args)
        self.need_install_driver_hosts = dict()

    def procedure(self):
        try:
            osd_ip_list = [osd.get('om_ip') for osd in self.osd_list]
            check_ret, fail_list = self.operate.check_host_list_ping(osd_ip_list)
            if not check_ret:
                err_msg = "There are some nodes%s that are not up to reach" % fail_list
                logger.error(err_msg)
                raise Exception(err_msg)

            logger.info("Get all driver packages")
            all_drivers = self.get_all_driver_list()

            logger.info("Install all package on storage nodes")
            for same_account_nodes in self.need_install_driver_hosts.values():
                user, passwd, root_pwd, nodes_ip_and_driver_info = same_account_nodes
                driver_and_ip_list = InstallDriverOperate.sort_drivers(nodes_ip_and_driver_info, all_drivers)
                logger.info("Installing All Drivers and Nodes is : %s" % driver_and_ip_list)
                for driver_and_ip in driver_and_ip_list:
                    driver, ip_list = driver_and_ip
                    driver_obj = DriverApi(self.project_id, ip_list, user, passwd, root_pwd)
                    driver_obj.install_driver(driver, timeout=600)

        except HCCIException as e:
            logger.error(traceback.format_exc())
            return Message(500, e)
        except Exception as e:
            logger.error("Failed install driver, details: %s" % str(e))
            return Message(500, HCCIException(626109, str(e)))
        return Message()

    def get_all_driver_list(self):
        client_list = list()
        all_drivers = list()
        logger.info('Start to get all driver')
        for host in self.osd_list:
            host_om_ip, user = host.get('om_ip'), host.get('user')
            passwd, root_pwd = host.get('passwd'), host.get('root_pwd')
            ssh_client = self.operate.create_ssh_root_client(host_om_ip, user, passwd, root_pwd)
            cpu_arch = self.operate.get_cpu_arch(ssh_client)
            driver_obj = DriverApi(self.project_id,
                                   os_ip_list=[host_om_ip],
                                   os_username=user, os_password=passwd,
                                   root_password=root_pwd)
            driver_info = driver_obj.get_nodes_driver_list_by_os(
                component="fusionstorage", node_type="fusionsphere", arch=cpu_arch).get(host_om_ip)
            driver_list = list(driver_info.keys())
            driver_list = self.operate.check_es3000_driver(ssh_client, cpu_arch, driver_list, 'management')
            logger.info("get node %s driver info: %s" % (host_om_ip, driver_list))
            client_list.append(ssh_client)
            if not driver_list:
                logger.info("There is no driver to need to install in current node[%s]." % host_om_ip)
                continue
            all_drivers.extend(driver_list)
            InstallDriverOperate.group_by_account_info(host, self.need_install_driver_hosts, driver_list)
            self.upload_install_script(host_om_ip, passwd, ssh_client, user)
        self.close_client_list(client_list)
        return all_drivers

    def upload_install_script(self, host_om_ip, passwd, ssh_client, user):
        remote_path = "/tmp/rpm_install_temp"
        cmd_tmp = "[ -d %s ] && rm -rf %s" % (remote_path, remote_path)
        ssh.ssh_send_command(ssh_client, cmd_tmp, "#", 60, 3)
        cmd_tmp = 'su - %s -s /bin/bash -c "mkdir -p %s; chmod 750 %s"' % (user, remote_path, remote_path)
        cmd_res = ssh.ssh_send_command(ssh_client, cmd_tmp, "#", 60, 3)
        logger.info("Make an directory on host[%s], result: %s" % (host_om_ip, str(cmd_res)))
        logger.info("Start to upload shell install script to host[%s]" % host_om_ip)
        driver_script = DeployConstant.DRIVER_SCRIPT[1]
        res = ssh.put_file(host_om_ip, user, passwd, driver_script, remote_path)
        logger.info("Upload package[%s] complete[%s]" % (driver_script, res))
        cmd_tmp = 'chown -h -R root:root %s' % remote_path
        ssh.ssh_send_command(ssh_client, cmd_tmp, "#", 60, 3)
        logger.info("Modify %s right success" % remote_path)

    @staticmethod
    def close_client_list(client_list):
        for client in client_list:
            if client:
                ssh.ssh_close(client)
