#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
获取产品包中xml文件数据
"""
import os
import shutil
import zipfile

import utils.common.log as logger
from utils.common.component_upgrade_common import read_xml
from utils.common.exception import FCUException
from utils.common.software_package_util import find_software_package


def get_patch_info(project_id):
    service_name = 'eBackup'
    pkg_re = "^OceanStor BCManager (.*)_eBackup_Patch_DMK.zip$"
    try:
        # 根据正则找产品包
        return_result = list()
        logger.info("Start looking for the %s product package." % service_name)
        pkg_dict, num = find_software_package(pkg_re, project_id)
        if num > 1:
            raise FCUException(111111, service_name)
        if not pkg_dict:
            raise FCUException(111110, service_name)
        pkg_name = list(pkg_dict.keys())[0]
        pkg_path = list(pkg_dict.values())[0]
        # 解压产品包中的xml配置文件到pkg临时目录下
        logger.info("Start extracting the xml configuration "
                    "file in the package.")
        xml_file_path, temp_dir_path = unzip_product_pkg(pkg_path,
                                                         pkg_name,
                                                         service_name)
        # 调用解析XML方法
        logger.info("Start getting xml configuration file content.")
        xml_content = read_xml(xml_file_path)
        # 删除临时文件夹
        logger.info("Start cleaning up temporary resource files.")
        shutil.rmtree(temp_dir_path)
        return_result.append(xml_content)
        return return_result
    except Exception as err_msg:
        logger.error('Failed to get the patch upgrade '
                     'information of the component(%s)' % err_msg)
        if isinstance(err_msg, FCUException):
            raise
        raise FCUException(111112, service_name, err_msg)


def unzip_product_pkg(pkg_path, pkg_name, service_name):
    """解压产品包中的xml配置文件到pkg临时目录下

    :param pkg_path: 工具pkg绝对路径
    :param pkg_name: 产品包名
    :param service_name: 服务名
    :return:
    """

    try:
        xml_file_path = None
        data_file_name = "UpdatePackageManifest.xml"
        temp_dir_path = os.path.join(pkg_path, r"%s_temporary" % service_name)
        max_size = 1 * 1024 * 1024 * 1024 * 10
        if os.path.exists(temp_dir_path):
            shutil.rmtree(temp_dir_path)
        os.makedirs(temp_dir_path)
        current_size = 0
        with zipfile.ZipFile(os.path.join(pkg_path, pkg_name), "r") as \
                zip_file:
            for each in zip_file.infolist():
                current_size += each.file_size()
                each_name = each.filename()
                if current_size < max_size:
                    if each_name == data_file_name:
                        xml_file_path = zip_file.extract(each, temp_dir_path)
                        break
                else:
                    raise Exception('The size of file to unzip exceeds max '
                                    'size %s byte allowed' % (str(max_size)))
        if xml_file_path is None:
            raise FCUException(111113, pkg_name)
        return xml_file_path, temp_dir_path
    except Exception as ex:
        logger.error('Unpacking the product package(%s) failed. '
                     'Failure reason:%s' % (service_name, ex))
        raise FCUException(111114, pkg_name, ex)
