# -*- coding: utf-8 -*-
import re
from plugins.ResourceCheck.common.libs import common_libs
from utils.common.fic_base import StepBaseInterface
from utils.common.fic_base import TestCase
from utils.common.message import Message
import utils.common.log as logger
import time
import os
from utils.business.project_condition_utils import get_project_conditions
from utils.common.exception import HCCIException
from utils.DBAdapter.DBConnector import BaseOps
from utils.common.ssh_util import Ssh

def open_file_util(file_name, mode='r', encoding=None, **kwargs):
    if mode in ['r', 'rt', 'tr'] and encoding is None:
        with open(file_name, 'rb') as f:
            context = f.read()
            for encoding_item in ['UTF-8', 'GBK', 'ISO-8859-1']:
                try:
                    context.decode(encoding=encoding_item)
                    encoding = encoding_item
                    break
                except UnicodeDecodeError as e:
                    pass
    return open(file_name, mode=mode, encoding=encoding, **kwargs)

class Do_Check_TenantFB_Slot(TestCase):
    def __init__(self, project_id, pod_id):
        self.this_path = os.path.realpath(__file__ + '/../..')
        self.this_path = os.path.realpath(__file__ + '/../..')
        self.script_dir = "/home/pkg/precheck/scripts/"
        self.thisPath = os.path.realpath(__file__ + '/../')
        self.local_dir = self.thisPath + '/shells/'
        self.rc_file = 'public_rcs'
        self.script_file = 'check_disk_slot_separate.sh'
        self.db = BaseOps()
        self.project_id = project_id
        self.pod_id = pod_id
        self.check_type='check_slot'

    def pre_condition(self):
        pass

    def create_check_script(self, script_src_file, script_file, **kwargs):
        script_dst_file = self.script_dir + script_file
        script_dst_dir_bak = self.script_dir + "bak/"
        script_dst_file_bak = script_dst_dir_bak + script_file
        check_type = ''
        timestamp = ''
        try:
            with open_file_util(script_src_file, 'r') as s:
                content = s.read()
            for item in kwargs.items():
                pattern = re.compile(item[0] + '=.*')
                repl = '%s=%s' % (item[0], item[1])
                content = re.sub(pattern, repl, content)
                if item[0] == 'TIMESTAMP':
                    timestamp = item[1]
                if item[0] == 'CHECKTYPE':
                    check_type = item[1]
            suffix = '_' + check_type + '_' + timestamp
            logger.info('Parsed params: %s' % kwargs)
            content = content.replace('\r', '')
            with open_file_util(script_dst_file, 'w', encoding='utf-8') as d:
                d.write(content)

            if not os.path.exists(script_dst_dir_bak):
                os.mkdir(script_dst_dir_bak)
            with open_file_util(script_dst_file_bak + suffix, 'w', encoding='utf-8') as b:
                b.write(content)
            logger.info('Successfully create checking script for %s, timestamp: %s, check type: %s' %
                        (script_file, timestamp, check_type))

        except Exception as e:
            logger.error(e)
            raise e

    def procedure(self):

        """
        检查管理节点、云服务节点的CPU
       """
        try:
            condition_dic = get_project_conditions(self.project_id)

            ssh_util = Ssh()
            bmc_ip_list = []
            timestamp = str(int(time.time()))

            nodes_info = self.db.get_install_os_list_info(self.pod_id)
            disk_slots = nodes_info[0].get('storagepool_slot')
            script_src_file = self.local_dir + self.script_file
            self.create_check_script(script_src_file, self.script_file,
                                     TIMESTAMP=timestamp,
                                     CHECKTYPE=self.check_type,
                                     DISKSLOTS=disk_slots)

            for node in nodes_info:
                bmc_ip = node.get('bmc_ip')
                manage_ip = node.get('manageIp')
                user_info_list = node.get('creuser').split(',')
                root_passwd = user_info_list[1]
                username = user_info_list[2]
                user_passwd = user_info_list[3]
                ssh_util.put_file(manage_ip, username, user_passwd, self.script_dir + self.rc_file,
                                  '/tmp')
                ssh_util.put_file(manage_ip, username, user_passwd, self.script_dir + self.script_file,
                                  '/tmp')
                ssh_client = Ssh.ssh_create_client(manage_ip, username, user_passwd)
                Ssh.ssh_send_command(ssh_client, 'LANG=C', '$', 2)
                Ssh.ssh_send_command(ssh_client, 'su', 'assword', 10)
                Ssh.ssh_send_command(ssh_client, root_passwd, '#', 10)
                Ssh.ssh_send_command(ssh_client, 'cd /tmp', '#', 10)
                Ssh.ssh_send_command(ssh_client, 'bash %s' % self.rc_file, '#', 30)
                Ssh.ssh_send_command(ssh_client, 'bash %s' % self.script_file, 'Successfully', 30)
                Ssh.ssh_close(ssh_client)
                bmc_ip_list.append(bmc_ip)

            common_libs.check_all_result(bmc_ip_list, self.check_type, timestamp)
            return True, None
        except HCCIException as e1:
            raise e1
        except Exception as e2:
            raise e2

    def post_condition(self):
        pass

    def failure(self):
        pass
        # 环境恢复脚本


class CheckTenantFBSlot(StepBaseInterface):
    def __init__(self, project_id, pod_id):
        super(CheckTenantFBSlot, self).__init__(project_id, pod_id)
        self.project_id = project_id
        self.pod_id = pod_id
        self.implement = Do_Check_TenantFB_Slot(project_id, pod_id)

    def pre_check(self, project_id, pod_id):
        """
        插件内部接口：执行安装前的资源预检查，该接口由execute接口调用，工具框架不会直接调用此接口。
        :param project_id:
        :param pod_id:
        :return:
        """
        pass

    def execute(self, project_id, pod_id):
        try:
            self.implement.procedure()
            return Message(200)
        except HCCIException as e1:
            return Message(500, e1)
        except Exception as e2:
            return Message(500, HCCIException('113999', str(e2)))

    def rollback(self, project_id, pod_id):
        """
        标准调用接口：执行回滚
        :param project_id:
        :param pod_id:
        :return:Message类对象
        """
        return Message(200)

    def retry(self, project_id, pod_id):
        """
        标准调用接口：重试
        :return: Message类对象
        """
        return self.execute(project_id, pod_id)

    def check(self, project_id, pod_id):
        """
        标准调用接口：重试
        :param project_id:
        :param pod_id:
        :return:
        """
        pass
