# -*- coding: utf-8 -*-
# Copyright (c) Huawei Technologies Co., Ltd. 2022-2023. All rights reserved.
import traceback
import utils.common.log as logger
from utils.common.exception import HCCIException
from plugins.DistributedStorage.common.upgrade_operate import UpgradeOperate
from plugins.DistributedStorage.common.base import TestCase


class StoragePoolCheck(TestCase):
    def __init__(self, project_id, pod_id, fs_args, **kwargs):
        super(StoragePoolCheck, self).__init__(project_id, pod_id)
        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 storage pool check task.')
        try:
            self.login_deploymanager()
        except HCCIException as e:
            logger.error('Storage pool check failed,details:{}'.format(e))
            logger.error(traceback.format_exc())
            raise e
        except Exception as e:
            logger.error('Storage pool check failed,details:{}'.format(e))
            logger.error(traceback.format_exc())
            raise HCCIException(621005, str(e)) from e

        logger.info('storage pool check.')
        try:
            fail_results = self.check_pool_status()
        except HCCIException as e:
            logger.error('Storage pool check failed,details:{}'.format(e))
            logger.error(traceback.format_exc())
            raise e
        except Exception as e:
            logger.error('Storage pool check failed,details:{}'.format(e))
            logger.error(traceback.format_exc())
            raise HCCIException(621005, str(e)) from e
        if fail_results:
            raise HCCIException(621005, str(fail_results))

    def check_pool_status(self):
        fail_results = []
        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_info = ret_data["storagePools"]
        for pool_info in storage_pools_info:
            pool_id = pool_info["poolId"]
            pool_status = pool_info["poolStatus"]
            if pool_status != 0:
                err_msg = "storage pool(%s) status(%s) is not normal" \
                          % (str(pool_id), str(pool_status))
                fail_results.append(err_msg)
                continue
            disk_failed_result = self._check_disk_info(pool_id)
            if disk_failed_result:
                fail_results.extend(disk_failed_result)
        return fail_results

    def login_deploymanager(self):
        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)

    def _check_disk_info(self, pool_id):
        fail_results = []
        ret_result, ret_data = self.opr.get_node_disk(pool_id)
        if ret_result != 0:
            err_msg = "get node disk failed, " \
                      "Detail:[result:%s, data:%s]" \
                      % (ret_result, ret_data)
            logger.error(err_msg)
            raise Exception(err_msg)
        nodes_infos = ret_data["nodeInfo"]
        for node_info in nodes_infos:
            if node_info["errorCode"] != 0:
                err_msg = "storage pool(%s) node(%s) errorCode(%s) " \
                          "is not normal" \
                          % (str(pool_id),
                             node_info["nodeMgrIp"],
                             str(node_info["errorCode"]))
                fail_results.append(err_msg)
            disks_infos = node_info["mediaInfo"]
            main_storage_count = 0
            for disk_info in disks_infos:
                # pools为空时表示该硬盘未加入存储池
                if not disk_info.get('pools'):
                    continue
                if disk_info["diskRole"] == "main_storage":
                    main_storage_count = main_storage_count + 1
                if disk_info["diskStatus"] != 0:
                    err_msg = "storage pool(%s) node(%s) " \
                              "disk slot(%s) status(%s) is not normal" \
                              % (str(pool_id),
                                 node_info["nodeMgrIp"],
                                 str(disk_info["diskSlot"]),
                                 str(disk_info["diskStatus"]))
                    fail_results.append(err_msg)
        return fail_results
