#!/usr/bin/env python
# -*- coding: UTF-8 -*-
from IPy import IP

from platforms.project.ProjectUtils import get_project_conditions, \
    get_project_condition_boolean as cond_bool
from platforms.project.lld.lld_sheet_basev2 import LldSheetBaseV2
from utils.DBAdapter.db_password import ParamPassword
from utils.common.param_check import check_param_ip
from utils.constant.FCDConstant import FCDConstant, DEVICETYPE as D_T
from plugins.DistributedStorage.scripts.utils.common.DeployConstant import DeployConstant


class FusionStorageSeperateDeploySheet(LldSheetBaseV2):
    def __init__(self, **kwargs):
        super(FusionStorageSeperateDeploySheet, self).__init__(**kwargs)
        self.input_data = kwargs.get('basic_content')
        self.template_data = []

    def set_template_data(self, *args, **kwargs) -> list:
        preset_dicts = {}
        project_conditions = get_project_conditions(self.project_id)
        is_cshastorage_tfb = project_conditions.get('CSHAStorage_TFB')
        is_csdrstorage_tfb = project_conditions.get('CSDRStorage_TFB')
        is_projectdeploy = project_conditions.get('ProjectDeploy')
        is_drstorage_tfb_sep = project_conditions.get('DRStorage_TFB_Sep')
        is_expansionadcloudservice_2 = project_conditions.get(
            'ExpansionAdCloudService')
        is_tenantstorfbhci = project_conditions.get('TenantStorFBHCI')
        is_tenantstorfbhci80 = project_conditions.get('TenantStorFBHCI80')
        deploy_component_index = 'deploy_component'
        if is_cshastorage_tfb or is_csdrstorage_tfb:
            if is_drstorage_tfb_sep:
                if is_projectdeploy:
                    preset_dicts = {1: {deploy_component_index: 'rep_ctl'},
                                    2: {deploy_component_index: 'rep_ctl'},
                                    3: {deploy_component_index: 'rep_ctl'},
                                    4: {deploy_component_index: 'osd'},
                                    5: {deploy_component_index: 'osd'},
                                    6: {deploy_component_index: 'osd'}}
                if is_expansionadcloudservice_2:
                    preset_dicts = {1: {deploy_component_index: 'rep_ctl'},
                                    2: {deploy_component_index: 'rep_ctl'},
                                    3: {deploy_component_index: 'rep_ctl'}}
            if is_projectdeploy and not is_drstorage_tfb_sep:
                preset_dicts = {1: {deploy_component_index: 'osd,rep_ctl'},
                                2: {deploy_component_index: 'osd,rep_ctl'},
                                3: {deploy_component_index: 'osd,rep_ctl'},
                                4: {deploy_component_index: 'osd,rep'},
                                5: {deploy_component_index: 'osd,rep'},
                                6: {deploy_component_index: 'osd,rep'}}
            if is_drstorage_tfb_sep and (
                    is_tenantstorfbhci or is_tenantstorfbhci80):
                if is_projectdeploy or is_expansionadcloudservice_2:
                    preset_dicts = {1: {deploy_component_index: 'rep_ctl'},
                                    2: {deploy_component_index: 'rep_ctl'},
                                    3: {deploy_component_index: 'rep_ctl'}}
        final_data = []
        for row_index, one_data_dict in preset_dicts.items():
            final_data.append(one_data_dict)
        self.template_data = final_data
        return final_data

    def set_summarising_data(self, *args, **kwargs) -> list:
        self.data = self.input_data.get("fusionstorage_business_server_list",
                                        []) if self.input_data else []
        return self.data

    def set_template_show_condition(self) -> bool:
        project_conditions = get_project_conditions(self.project_id)
        is_project_test = project_conditions.get('ProjectTest', 0)
        is_dcupgradeproject61t631 = project_conditions.get(
            'DCUpgradeProject61t631')
        is_cshastorage_tfb = project_conditions.get('CSHAStorage_TFB')
        is_csdrstorage_tfb = project_conditions.get('CSDRStorage_TFB')
        is_drstorage_tfb_sep = project_conditions.get('DRStorage_TFB_Sep')
        is_tenantstorfbhci = project_conditions.get('TenantStorFBHCI')
        is_tenantstorfbhci80 = project_conditions.get('TenantStorFBHCI80')
        is_projectmodifaction = project_conditions.get('ProjectModifaction')
        is_projectmodifactioniam = project_conditions.get(
            'ProjectModifactionIAM')
        ipv4tipv46 = project_conditions.get(
            'ServiceIPV4tServiceIPV46')
        is_expansion_cloud_service = project_conditions.get(
            'ExpansionCloudService')
        is_expan_scale_network_bmsgw = project_conditions.get(
            'ExpansionNetworkRes_BMSGW')
        # 技术中台和AI数据中台服务订阅
        is_expan_service_storage = project_conditions.get(
            'ExpansionServiceStorage')
        show = False
        if not (is_project_test or (is_projectmodifaction and ipv4tipv46) or
                is_projectmodifactioniam):
            if not is_dcupgradeproject61t631:
                show = self._get_not_dcupgrade_show(is_cshastorage_tfb, is_csdrstorage_tfb, is_drstorage_tfb_sep,
                                                    is_tenantstorfbhci, is_tenantstorfbhci80)
            # 新增业务存储 工程
            if is_expan_service_storage:
                show = True
            # 技术中台和AI数据中台服务订阅
            elif is_expansion_cloud_service:
                show = False
            if is_expan_scale_network_bmsgw:
                show = False
        return show

    def _get_not_dcupgrade_show(self, is_cshastorage_tfb, is_csdrstorage_tfb, is_drstorage_tfb_sep, is_tenantstorfbhci,
                                is_tenantstorfbhci80):
        show = False
        if cond_bool(
                self.project_id,
                "((TenantStorFB | TenantStorFB80) &"
                "ProjectDeploy) | (((TenantStorFB | TenantStorFB80) |"
                "(TenantStorFBReuse |  TenantStorFBReuse80)) & "
                "(ExpansionPOD_BMS | ExpansionPOD_KVM |"
                "ExpansionAZ_KVM | ExpansionAZ_BMS))"):
            show = True
        if (is_cshastorage_tfb or is_csdrstorage_tfb) \
                and is_drstorage_tfb_sep:
            show = True
        if (is_tenantstorfbhci or is_tenantstorfbhci80) \
                and is_drstorage_tfb_sep:
            show = True
        return show

    def set_summarising_show_condition(self) -> bool:
        return self.set_template_show_condition()

    def set_summarising_col_show_condition(self) -> dict:
        return self.set_template_col_show_condition()

    def set_template_col_show_condition(self, *args, **kwargs) -> dict:
        col_show_dict = {}
        cond = get_project_conditions(self.project_id)
        is_cshastorage_tfb = cond.get('CSHAStorage_TFB')
        is_csdrstorage_tfb = cond.get('CSDRStorage_TFB')
        t_storfb_hete = cond.get('TenantStorFB_Heterogeneous')
        t_stor_back_sep = cond.get('TenantStorBackendNetSep')
        is_tenantstorfb = cond.get('TenantStorFB')
        is_tenantstorfb80 = cond.get('TenantStorFB80')
        is_tenantstorfbreuse = cond.get('TenantStorFBReuse')
        is_tenantstorfbreuse80 = cond.get('TenantStorFBReuse80')
        is_expansion_az = cond.get('ExpansionAZ')
        is_exp_service_storage = cond.get('ExpansionServiceStorage')

        if not (is_cshastorage_tfb or is_csdrstorage_tfb):
            col_show_dict["deploy_component"] = False
            col_show_dict["replication_cluster_meta_info"] = False
            col_show_dict["replication_cluster_meta_type"] = False
        self._set_col_show_with_t_storfb_hete(t_storfb_hete, col_show_dict, is_cshastorage_tfb, is_csdrstorage_tfb)
        if (is_exp_service_storage and is_csdrstorage_tfb and not is_tenantstorfb80):
            col_show_dict['storage_pool_type'] = False
            col_show_dict['storage_pool_name_and_slot'] = False
        if not t_stor_back_sep:
            col_show_dict["storage_inner_plane"] = False
            col_show_dict["storageInnerIp"] = False
        if not (t_storfb_hete and is_cshastorage_tfb):
            col_show_dict["arbitration_plane_ip"] = False
        if not (t_storfb_hete and (is_cshastorage_tfb or is_csdrstorage_tfb)):
            col_show_dict["replication_plane_ip"] = False
        self._set_some_col_show(col_show_dict, is_expansion_az,
                                is_tenantstorfb, is_tenantstorfb80,
                                is_tenantstorfbreuse, is_tenantstorfbreuse80)
        self.col_show_dict = col_show_dict
        return col_show_dict

    def _set_col_show_with_t_storfb_hete(self, t_storfb_hete, col_show_dict, is_cshastorage_tfb, is_csdrstorage_tfb):
        if t_storfb_hete:
            col_show_dict["management_plane"] = False
            col_show_dict["storage_plane"] = False
            col_show_dict["storage_inner_plane"] = False
        if not (not t_storfb_hete and (
                is_cshastorage_tfb or is_csdrstorage_tfb)):
            col_show_dict["replication_plane"] = False
        if not t_storfb_hete:
            col_show_dict["manageIp"] = False
            col_show_dict["storageIp"] = False
            col_show_dict["storageInnerIp"] = False

    def _set_some_col_show(self, col_show_dict, is_expansion_az,
                           is_tenantstorfb, is_tenantstorfb80,
                           is_tenantstorfbreuse, is_tenantstorfbreuse80):
        if not ((is_tenantstorfb or is_tenantstorfb80) or (
                is_tenantstorfbreuse or is_tenantstorfbreuse80)):
            col_show_dict["is_metadata_node"] = False
            col_show_dict["storage_pool_name"] = False
            col_show_dict["storagepool_redundancy_policy"] = False
            col_show_dict["ec_ratio"] = False
            col_show_dict["ec_block_size"] = False
            col_show_dict["ec_cache"] = False
            col_show_dict["zk_slot"] = False
            col_show_dict["zk_type"] = False
            col_show_dict["storagepool_slot"] = False
            col_show_dict["primary_slot"] = False
            col_show_dict["primary_type"] = False
            col_show_dict["cache_type"] = False
        if not (is_tenantstorfb or is_tenantstorfbreuse):
            col_show_dict["storagepool_slot"] = False
        # fsb6.3时的EC的3个参数不再使用。
        col_show_dict["ec_ratio"] = False
        col_show_dict["ec_block_size"] = False
        col_show_dict["ec_cache"] = False
        # fsb8.False EC使用两个新的参数。
        if not (is_tenantstorfb80 or is_tenantstorfbreuse80):
            col_show_dict["ec_verify_fragments"] = False
            col_show_dict["ec_data_fragments"] = False
        if is_tenantstorfbreuse and is_expansion_az:
            col_show_dict["storage_pool_type"] = False
        if cond_bool(self.project_id,
                     "ExpansionAZ & TenantStorFBReuse80"):
            col_show_dict["is_metadata_node"] = False
            col_show_dict["zk_slot"] = False
            col_show_dict["zk_type"] = False
        if cond_bool(
                self.project_id,
                "ExpansionServiceStorage & (TenantStorNewPool | "
                "TenantStorNewNode)"):
            col_show_dict["is_metadata_node"] = False
            col_show_dict["zk_slot"] = False
            col_show_dict["zk_type"] = False
            col_show_dict["primary_slot"] = True
            col_show_dict["primary_type"] = True
            col_show_dict["cache_type"] = True
            col_show_dict["storagepool_redundancy_policy"] = True
            col_show_dict["ec_verify_fragments"] = True
            col_show_dict["ec_data_fragments"] = True

    def set_down_list(self) -> dict:
        down_list_dict = {}
        cond = self.project_conditions
        t_storfb_hete = cond.get('TenantStorFB_Heterogeneous')
        exp_az = cond.get('ExpansionAZ')
        exp_pod = cond.get('ExpansionPOD')
        t_storfbreuse = cond.get('TenantStorFBReuse')
        project_type = str(self.project_info['project_type'])

        down_list_arm = D_T.TaiShan2280_LIST + D_T.TaiShan5280_LIST
        down_list_arm_odk = D_T.TaiShan2280_LIST + D_T.TaiShan5280_LIST
        if project_type == str(FCDConstant.PROJECT_DEPLOY):
            if t_storfb_hete:
                down_list_arm = D_T.TaiShan2280_LIST + D_T.TaiShan5280_LIST
            else:
                down_list_arm_odk = D_T.TaiShan2280_LIST + D_T.TaiShan5280_LIST
        if (project_type == str(FCDConstant.PROJECT_EXPANSION)) and (
                exp_az or exp_pod):
            if t_storfb_hete:
                down_list_arm = D_T.TaiShan2280_LIST + D_T.TaiShan5280_LIST
            else:
                down_list_arm_odk = D_T.TaiShan2280_LIST + D_T.TaiShan5280_LIST
        equ_down_list = self.get_equ_down_list(t_storfb_hete, exp_az, t_storfbreuse, down_list_arm, down_list_arm_odk)
        down_list_dict["equipment_model"] = equ_down_list

        # 业务存储商业模式上只支持EC
        if cond_bool(self.project_id, "ExpansionAZ & TenantStorFBReuse"):
            storagepool_redundancy_policy_list_1_4 = ['3Redundancy']
        else:
            storagepool_redundancy_policy_list_1_4 = ['ec']
        down_list_dict["storagepool_redundancy_policy"] = storagepool_redundancy_policy_list_1_4
        return down_list_dict

    def get_equ_down_list(self, t_storfb_hete, exp_az, t_storfbreuse, down_list_arm, down_list_arm_odk):
        down_list_x86 = down_list_x86_odk = DeployConstant.LLD_DOWN_LIST_X86

        if t_storfb_hete:
            if exp_az and t_storfbreuse:
                equ_down_list = down_list_x86
            else:
                equ_down_list = down_list_x86 + down_list_arm
        else:
            if exp_az and t_storfbreuse:
                equ_down_list = down_list_x86_odk
            else:
                equ_down_list = down_list_x86_odk + down_list_arm_odk
        if 'GENERAL' not in equ_down_list:
            equ_down_list.append('GENERAL')
        return equ_down_list

    def set_comment(self) -> dict:
        is_tenantstorfb80 = self.project_conditions.get('TenantStorFB80')
        storagepool_redundancy_policy_comment = \
            self.lld_cfg.get_lld_param_value(
                'storagepool_redundancy_policy_comment') + \
            self.lld_cfg.get_lld_param_value(
                'osd_in_deploy_component_need_to_fill_in')
        storagepool_redundancy_policy_comment_80 = \
            self.lld_cfg.get_lld_param_value(
                'storagepool_redundancy_policy_comment_80') + \
            self.lld_cfg.get_lld_param_value(
                'osd_in_deploy_component_need_to_fill_in')

        if is_tenantstorfb80:
            storagepool_redundancy_policy_comment = \
                storagepool_redundancy_policy_comment_80

        comment_dict = {
            "storagepool_redundancy_policy":
                storagepool_redundancy_policy_comment}
        return comment_dict

    def read_data_from_excel_file(self, file_path, sheet_name):

        '''
        获取 1.4华为分布式块存储分离部署参数
        :return:
        '''

        flag, data_list = super(FusionStorageSeperateDeploySheet,
                                self).read_data_from_excel_file(file_path,
                                                                sheet_name)
        if not flag:
            return flag, data_list
        project_conditions = get_project_conditions(self.project_id)
        is_tenantstorfb80 = project_conditions.get('TenantStorFB80')
        is_tenantstorfbreuse80 = project_conditions.get('TenantStorFBReuse80')
        is_tenantstorfb80_all = is_tenantstorfb80 or is_tenantstorfbreuse80
        for item in data_list:
            if is_tenantstorfb80_all:
                if item.get('primary_slot'):
                    item['storagepool_slot'] = item.get('primary_slot')
            if not item.get('is_metadata_node', None):
                item['is_metadata_node'] = ""
            else:
                item['is_metadata_node'] = item.get('is_metadata_node', "")
            ec_block_size = item.get('ec_block_size')
            item['ec_block_size'] = ec_block_size if ec_block_size else 0
            fs_bmc_ip = item.get('bmc_ip')
            if fs_bmc_ip:
                is_ipv6 = check_param_ip(fs_bmc_ip, ip_version=6)
                item['bmc_ip'] = IP(
                    fs_bmc_ip).strCompressed() if is_ipv6 else fs_bmc_ip

        return True, data_list

    def back_input_old_password_for_ui_data(self, data):
        pod_list = self.db_base.get_project_pods_by_id(self.project_id)
        for pod in pod_list:
            # 密码还原
            if len(data) == 0:
                continue
            is_tenantstorfb80 = self.project_conditions.get('TenantStorFB80')
            is_tenantstorfbreuse80 = self.project_conditions.get(
                'TenantStorFBReuse80')
            is_tenantstorfb80_all = is_tenantstorfb80 or is_tenantstorfbreuse80
            old_os_data = self.db_base.get_install_os_list_info(
                pod["pod_id"], 'all')
            self._get_old_info_by_ip(data, is_tenantstorfb80_all, old_os_data)

    @staticmethod
    def _get_old_info_by_ip(data, is_tenantstorfb80_all, old_os_data):
        for new_fs_unit in data:
            if is_tenantstorfb80_all:
                if new_fs_unit.get('primary_slot'):
                    new_fs_unit['storagepool_slot'] = new_fs_unit.get(
                        'primary_slot')
            for old_fs_unit in old_os_data:
                if new_fs_unit.get("bmc_ip") != old_fs_unit["bmc_ip"]:
                    continue
                new_fs_unit["creuser"] = ParamPassword.saveback(
                    new_fs_unit["creuser"].get("creuser"),
                    old_fs_unit["creuser"])
                if new_fs_unit.get("bmc_passwd", None):
                    new_fs_unit["bmc_passwd"] = ParamPassword.saveback(
                        new_fs_unit["bmc_passwd"].get("bmc_passwd"),
                        old_fs_unit["bmc_passwd"])
                break
