#coding:utf-8
import traceback
import os
import json
from zipfile import ZipFile
from xml.dom.minidom import parse
import xml.dom.minidom
import shutil
'''用于比对出APP的依赖与平台的commmonlib的脚本'''

class CompareDependency(object):
    #appname:app名称，如bsa_ata
    #apppath:打包平台上此时app的绝对路径
    #jarpath:需比对的app jar文件的绝对路径
    #depath:平台de文件所在的绝对路径
    #name:文件名；启动job/进程时的依赖需要从中读取
    def __init__(self, appname, apppath, jarpath, depath, name):
        self.bsaroot = "${BSA_HOME}"
        self.platform_libpath = self.bsaroot + "/libs/Java/commonLibs"
        self.jarpath = jarpath
        self.depath = depath
        self.name = name
        self.pom_path = os.path.dirname(os.path.dirname(self.jarpath)) + "/pom.xml"
        self.lib_path = os.path.dirname(self.jarpath) + "/lib"
        self.apppath = apppath
        self.appname = appname

    def parse_manifest(self, cpath):
        '''解析MANIFEST.MF文件'''
        ls = list()

        f = ZipFile(cpath)
        try:
            content = f.read("META-INF/MANIFEST.MF").split("\n")
            content_ls = list()
            start = False
            for line in content:
                if line.startswith("Class-Path:"):
                    content_ls.append(line.replace("Class-Path:", "").replace("\r", "").replace("\n", ""))
                    start = True
                else:
                    if start:
                        if line.find(':') != -1:
                            break
                        else:
                            content_ls.append(line.replace("\r", "").replace("\n", "")[1:])
            ls = ("".join(content_ls)).strip().split(" ")
        except Exception, e:
            traceback.print_exc()
            raise e
        finally:
            f.close()
        return ls

    def get_de_fullpath(self):
        '''根据依赖的dm版本得到de.jar的版本，从而得到绝对路径'''
        de_path = None
        try:
            if os.path.exists(self.pom_path):
                domtree = xml.dom.minidom.parse(self.pom_path)
                root = domtree.documentElement
                node1 = root.getElementsByTagName("dependencyManagement")
                node2 = node1[0].getElementsByTagName("dependencies")
                node3 = node2[0].getElementsByTagName("dependency")
                for item in node3:
                    group = item.getElementsByTagName("groupId")[0].childNodes[0].nodeValue
                    artifact = item.getElementsByTagName("artifactId")[0].childNodes[0].nodeValue
                    if group == 'com.nsfocus.bsa' and artifact == 'dm':
                        version = item.getElementsByTagName("version")[0].childNodes[0].nodeValue
                        de_path = self.depath + "/de-%s.jar"%(version,)
                        break
        except Exception, e:
            traceback.print_exc()
            raise e
        return de_path

    def compare(self):
        '''进行比对，并且输出结果;用于spark job和普通java进程'''
        app_de = self.parse_manifest(self.jarpath)
        platform_de_fullpath = self.get_de_fullpath()
        if platform_de_fullpath is not None:
            confdic = {"common":[], "privacy":[]}
            platform_de = self.parse_manifest(platform_de_fullpath)
            #可以使用平台的jar,取交集
            common_jars = list(set(app_de) & set(platform_de))
            #只能使用app自己的jar，取差集
            diff_jars = list(set(app_de).difference(set(platform_de)))
            #app jar依赖的私有jar路径
            privacy_jar_path = os.path.normpath(self.apppath + "/bin/lib/" + \
                os.path.basename(self.jarpath).replace(".jar", "").replace("-","_").replace(".",""))
            if not os.path.exists(self.apppath + "/bin/lib"):
                os.mkdir(self.apppath + "/bin/lib")
            if not os.path.exists(privacy_jar_path):
                os.mkdir(privacy_jar_path)
            for item in diff_jars:
                items = item.split("@")
                srcpath = os.path.normpath(self.lib_path + "/" + items[0] + "." \
                    + items[1] + "-" + items[2] + ".jar")
                dstpath = os.path.normpath(privacy_jar_path + "/" + items[0] + "." \
                    + items[1] + "-" + items[2] + ".jar")
                shutil.copy(srcpath, dstpath)
                confdic["privacy"].append(os.path.normpath(dstpath.replace(os.path.normpath(self.apppath), \
                    self.bsaroot + "/apps/" + self.appname)).replace("\\", "/"))
            for item in common_jars:
                items = item.split("@")
                confdic["common"].append(self.platform_libpath + "/" + items[0] + "." \
                    + items[1])
            confpath = self.apppath + "/conf/" + self.name 
            open(confpath, "w").write(json.dumps(confdic))
            print "write conf file:", confpath
