# -*- coding: utf-8 -*-
import utils.common.log as logger
from utils.common.exception import HCCIException
from plugins.DistributedStorage.common.UpgradeOperate import UpgradeOperate
from plugins.DistributedStorage.common.base import TestCase
import traceback


class DisksCheck(TestCase):
    def __init__(self, project_id, pod_id, fs_args, condition=None,
                 metadata=None, **kwargs):
        super(DisksCheck, self).__init__(project_id, pod_id)
        self.condition = condition
        self.metadata = metadata
        self.more_args = kwargs
        self.opr = UpgradeOperate(fs_args)
        self.user_name = fs_args["user_name"]
        self.password = fs_args["password"]

    def procedure(self):
        logger.info('Start disk check task.')
        try:
            fail_results = []
            status_code, error_code, error_des = self.opr.try_login(
                self.user_name, self.password)
            if status_code != 200 or error_code != 0:
                err_msg = "login failed, Detail:[status:%s, code:%s]%s" % (status_code, error_code, error_des)
                logger.error(err_msg)
                raise Exception(err_msg)

            logger.info('disk check.')
            ret_result, ret_data = self.opr.get_storage_pool()
            if ret_result != 0:
                err_msg = "get storage pool failed, " \
                          "Detail:[result:%s, data:%s]" \
                          % (ret_result, ret_data)
                logger.error(err_msg)
                raise Exception(err_msg)
            # 获取集群内所有存储池
            storage_pools = ret_data["storagePools"]
            pool_id_list = self._get_pool_id_list(storage_pools)
            for pool_id in pool_id_list:
                # 获取存储池信息
                ret_result, ret_data = self.opr.get_node_disk(pool_id)
                if ret_result != 0:
                    err_msg = "get pool info failed, Detail:[result:%s, data:%s]" \
                              % (ret_result, ret_data)
                    logger.error(err_msg)
                    raise Exception(err_msg)
                host_infolist = ret_data["nodeInfo"]
                for host_info in host_infolist:
                    disk_failed = self._get_disk_failed(host_info)
                    fail_results.extend(disk_failed)
            if fail_results:
                raise HCCIException(621005, str(fail_results))

        except HCCIException as e:
            logger.error('disk check task failed,details:{}'.format(e))
            logger.error(traceback.format_exc())
            raise e
        except Exception as e:
            logger.error(' disk check task failed,details:{}'.format(e))
            logger.error(traceback.format_exc())
            raise HCCIException(621005, str(e))

    @staticmethod
    def _get_pool_id_list(storage_pools):
        pool_id_list = []
        for storage_pool in storage_pools:
            pool_id = storage_pool.get("poolId")
            if pool_id is None:
                logger.error("get poolID failed")
                continue
            pool_id_list.append(pool_id)
        return pool_id_list

    @staticmethod
    def _get_disk_failed(host_info):
        fail_results = []
        disk_infos = host_info["mediaInfo"]
        host_ip = host_info["nodeMgrIp"]
        for disk_info in disk_infos:
            # pools为空时表示该硬盘未加入存储池
            if not disk_info.get('pools'):
                continue
            disk_status = disk_info["diskStatus"]
            if disk_status != 0:
                err_msg = "server(%s) disk slot(%s) status(%s) is not normal" \
                          % (host_ip, str(disk_info["diskSlot"]), str(disk_status))
                fail_results.append(err_msg)
        return fail_results
