# -*- coding: utf-8 -*-
#
# Tencent is pleased to support the open source community by making QTA available.
# Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
# Licensed under the BSD 3-Clause License (the "License"); you may not use this
# file except in compliance with the License. You may obtain a copy of the License at
#
# https://opensource.org/licenses/BSD-3-Clause
#
# Unless required by applicable law or agreed to in writing, software distributed
# under the License is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS
# OF ANY KIND, either express or implied. See the License for the specific language
# governing permissions and limitations under the License.
#
"""
扩展库管理（仅独立模式使用）
"""

import os
import zipfile
import shutil
import logging
import xml.dom.minidom as dom

from testbase.util import codecs_open


class ExLibManager(object):
    """扩展库管理器"""

    def __init__(self, proj_root):
        self._top_dir = proj_root
        self._installed_libs = os.path.join(
            self._top_dir, "exlib", "installed_libs.txt"
        )

    def _get_egg_name(self, egg_path):
        """获取egg包名称"""
        with zipfile.ZipFile(egg_path, "r") as egg:
            with egg.open("EGG-INFO/PKG-INFO", "r") as fd:
                for line in fd.readlines():
                    if line.startswith("Name:"):
                        return line.split(":")[1].strip()

    def install(self, egg_path):
        """安装"""
        # 获取全部的顶级package
        toplv_pkgs = []
        with zipfile.ZipFile(egg_path, "r") as egg:
            for f in egg.filelist:
                items = f.filename.split("/")
                if len(items) == 2 and items[1].lower() == "__init__.py":
                    toplv_pkgs.append(items[0])

        exlib_dir = os.path.join(self._top_dir, "exlib")
        if not os.path.isdir(exlib_dir):
            os.makedirs(exlib_dir)

        # 移除老的包
        egg_name = self._get_egg_name(egg_path)
        egg_paths_remove = []
        if egg_name:
            for file_name in os.listdir(exlib_dir):
                if not file_name.lower().endswith(".egg"):
                    continue
                file_path = os.path.join(exlib_dir, file_name)
                if not os.path.isfile(file_path):
                    continue
                if egg_name == self._get_egg_name(file_path):
                    os.remove(file_path)
                    egg_paths_remove.append(file_path)

        # 拷贝包
        shutil.copy(egg_path, exlib_dir)

        # 记录到installed_libs.txt
        installed_pkgs = self.list_names()
        for pkg in toplv_pkgs[:]:
            if pkg in installed_pkgs:
                toplv_pkgs.remove(pkg)
        if toplv_pkgs:
            with codecs_open(self._installed_libs, "a+") as fd:
                for pkg in toplv_pkgs:
                    fd.write(pkg + "\n")

        self._update_pydev_conf(egg_path, egg_paths_remove)

    def _update_pydev_conf(self, egg_path, egg_paths_remove):
        """修改pydev配置"""
        egg_names_remove = []
        for it in egg_paths_remove:
            egg_names_remove.append(os.path.basename(it).lower())
        egg_name = os.path.basename(egg_path)

        #         if len(egg_names_remove) == 1 and egg_names_remove[0] == egg_name:
        #             return

        pydev_path = os.path.join(self._top_dir, ".pydevproject")
        if not os.path.isfile(pydev_path):
            logging.warn("pydev configure file not found")
            return
        doc = dom.parse(pydev_path)
        for propnode in doc.getElementsByTagName("pydev_pathproperty"):
            if propnode.getAttribute("name") == "org.python.pydev.PROJECT_SOURCE_PATH":
                break
        else:
            propnode = doc.createElement("pydev_pathproperty")
            propnode.setAttribute("name", "org.python.pydev.PROJECT_SOURCE_PATH")
            projnodes = doc.getElementsByTagName("pydev_project")
            if not projnodes:
                logging.warn("pydev configure file corrupted")
                return
            projnodes[0].AppendChild(propnode)

        for pathnode in propnode.getElementsByTagName("path"):
            file_path = pathnode.childNodes[0].data
            name = file_path[file_path.rfind("/") + 1 :]
            if name.lower() in egg_names_remove:
                propnode.removeChild(pathnode)

        pathnode = doc.createElement("path")
        print(egg_name)
        pathnode.appendChild(
            doc.createTextNode("/${PROJECT_DIR_NAME}/exlib/%s" % egg_name)
        )
        propnode.appendChild(pathnode)
        with codecs_open(pydev_path, "w", "utf8") as fd:
            fd.write(doc.toxml(encoding="UTF-8"))

    def list_names(self):
        """获取全部的扩展包的名字"""
        if not os.path.isfile(self._installed_libs):
            return []
        names = []
        with codecs_open(self._installed_libs, "r", encoding="utf-8") as fd:
            for libname in fd.readlines():
                libname = libname.strip("\r\n ")
                if not libname:
                    continue
                names.append(libname)
        return names
