#!/usr/bin/env python
# -*- coding:utf-8 -*-
## create by shen,2018.06.22 601084713

import os, sys, time
import subprocess
import argparse
import HfsSql
import re, json, gzip
import hou, fnmatch
import traceback
import codecs


class HoudiniAnalyse():
    runcode = True
    runend = False

    def __init__(self, args):
        self._args = args
        self._ext = [".py", ".hda"]
        self.db_dir = self._check_and_mk()
        self.sequence_type_list = [r"%(UDIM)d", r"<udim>"]
        self.CreateBasedate()
        self.op_list = []
        self.fs_list = []
        self.global_V = ["ACTIVETAKE", "DRIVER", "DRIVERPATH", "EYE", "E", "HANDLE_STATUS", "HIPFILE", "HIPNAME", "HIP",
                         "JOB", "PI", "POSE", "_HIP_SAVEPLATFORM", "_HIP_SAVETIME", "_HIP_SAVEVERSION",
                         "_HIP_SHELFTOOLCOUNT", "status"]
        self.render_types = ['ifd', 'arnold', 'Redshift_ROP']
        self.excl_fn_list = ['mantra.ifd', 'dcm.rat', 'dsm.rat', 'test.ifd']
        self.excl_nodetype_list = ['ifd']
        self.excl_ext_list = ['.pc']

    def _check_and_mk(self):
        """Check the path to the DB data file generated by the upload asset."""
        db_path = os.environ.get("RAYVISION_HOUDINI")
        if not db_path:
            if sys.platform.startswith("win"):
                db_path = os.path.join(os.environ["USERPROFILE"], "renderfarm_sdk")
            else:
                db_path = os.path.join(os.environ["HOME"], "renderfarm_sdk")
        return db_path

    def CreateBasedate(self):
        if os.path.exists(self._args.task):
            with open(self._args.task, "rb") as f:
                self.task_adict = json.load(f)
                f.close()
        else:
            self.task_adict = {}

        self._temp_path = "%s/data_tl.db" % self.db_dir.replace("\\", "/")
        print("Houdini DB PATH ==> %s" % self._temp_path)
        new_data = True if not os.path.exists(self._temp_path) else False

        ## preset the date ,such as table named:ReFerType,node type ,just input "file"
        self._refer_table = "ReFerType"
        self._sl, self._cur = HfsSql.connectsl(self._temp_path, self._refer_table)
        if new_data: HfsSql.insertToTable(self._sl, self._cur, self._refer_table, ["TYPES"], ["file"])

        ## check result
        # if 0:
        #     cursor = HfsSql.getTableInfo_typs(self._cur,self._refer_table,["TYPES"])
        #     ## get typelist
        #     for elm in cursor:
        #         if elm[0] == "file":
        #             print("elm",elm[0])
        self.GetNodeTypeData()

    def GetNodeTypeData(self):
        cursor = HfsSql.getTableInfo_typs(self._cur, self._refer_table, ["TYPES"])
        # get typelist
        self._typelist = []
        for elm in cursor:
            # print("elm",elm)
            self._typelist.append(elm[0])
        # print_times(self._typelist)

    def loadhipfile(self):
        try:
            hou.setSimulationEnabled(False)
            hou.setUpdateMode(hou.updateMode.Manual)
            print("set Simulation off")
            print("set updateMode Manual")
        except OSError as e:
            print(e)

        self.hip_file = self._args.project.replace("\\", "/")
        if os.path.exists(self.hip_file):
            print_times("Loading hip file: %s" % self.hip_file)
            try:
                hou.hipFile.load(self.hip_file)
                print_times("Loading hip file success")
                # update $HIP once file loaded
                _hip_val = os.path.dirname(self.hip_file)
                hou.hscript("setenv HIP=" + str(_hip_val))
                hou.hscript("varchange")

            except (IOError, ZeroDivisionError) as e:
                print_times(e)
        else:
            print_times("ERROR: the hip file is not exist!")
            sys.exit(1)

    @staticmethod
    def GetSaveVersion(hipfile=""):
        _hfs_save_version = ''
        _hip_save_val = ''
        if os.path.exists(hipfile):
            with open(hipfile, "rb") as hipf:
                Not_find = True
                search_elm = 2
                search_elm_cunt = 0
                while Not_find:
                    line = str(hipf.readline()).encode("utf-8")
                    if "set -g _HIP_SAVEVERSION = " in str(line):
                        # print(str(line))
                        pattern = re.compile("[\d+\d+\d+]")
                        _HV = pattern.findall(str(line))
                        if len(_HV) > 6: _HV = _HV[:6]
                        _hfs_save_version = int(''.join(elm for elm in _HV))
                        _hfs_save_version = "%s.%s.%s" % (str(_hfs_save_version)[:2],
                                                          str(_hfs_save_version)[2:3], str(_hfs_save_version)[3:])
                        search_elm_cunt += 1

                    # The $HIP val with this file saved
                    if "set -g HIP = " in str(line):
                        pattern = re.compile("\\'.*\\'") if sys.version[:1] == "2" else re.compile(r"\\'.*\\'")
                        _Hip = pattern.search(str(line)).group()
                        _hip_save_val = _Hip.split("\'")[1].replace("\\", "/")
                        search_elm_cunt += 1
                    if search_elm_cunt >= search_elm:
                        Not_find = False
        else:
            print("The .hip file is not exist.")
            _hfs_save_version, _hip_save_val = ("", "")
        return _hfs_save_version, _hip_save_val

    def GetAssets(self):
        if not self.runcode:
            self.runend = True
            sys.exit(886)
        ## eg. asset = {"Normal":{"node1":["filename",["files"]],"node2":["filename",["files"]]},
        ##                    "Miss":{"node1":["filename",["files"]],"node2":["filename",["files"]]}}
        Miss_adict = {}
        Normal_adict = {}
        folder_adict = {}
        search_adict = {}
        file_adict = {}
        # self.getReferenceFiles()
        # self.fs_list = list(set(self.fs_list))
        print("It run hou.fileReferences()")
        try:
            print("It is runing here ")
            file_adict = hou.fileReferences()
            print_times("hou.fileReferences: %s" % len(file_adict))
        except Exception as e:
            print("hou.fileReferences--%s" % e)

        print("==============================================================================")
        exclude_list = ['soho_program', 'env_skymap', 'shadowmap_file', 'kernelfile', 'cachedir', 'layers',
                        'filedef', 'cuspfile', 'inputgeo',
                        'transformgroups', 'clips', 'cachedir', 'rig', 'shapelib', 'vm_dcmfilename', 'prerender',
                        'preframe', 'postframe', 'ass_file',
                        'postwrite', 'postrender', 'maskname', 'restvolumes', 'displacefile']
        exclude_eval_list = ['Helvetica Bold', 'voptype.h voplib.h', 'ocean.h', 'voplib.h']

        for elm in file_adict:
            # for elm in self.fs_list:
            if elm[0] != None:
                temp_node = elm[0].node()
                temp_node_type = temp_node.type().name()
                if temp_node_type in  self.render_types:
                    continue
             
            if elm[0] != None and elm[0].name() not in exclude_list and elm[0].eval() not in exclude_eval_list:
                print_times("elm[0].node(): {0}".format(elm[0].node().path()))
                print_times("elm[0].eval(): {0}".format(elm[0].eval()))
                if self.isFile(self.str_to_unicode(str(elm[0].eval()))):
                    # print_times("File in : {0}".format(elm[0].eval()))
                    if not elm[0].name() in self._typelist and len(elm[-1]):
                        if not os.path.splitext(elm[-1])[-1] in self._ext:
                            HfsSql.insertToTable(self._sl, self._cur, self._refer_table, ["TYPES"], [elm[0].name()])
                            self._typelist.append(elm[0].name())
                        else:
                            pass  ## hda else

                    if self.isFile(self.str_to_unicode(elm[-1])):
                        # print_times("File in str_to_unicode: {0}".format(elm[-1]))
                        file_split = os.path.split(elm[0].eval())
                        # print_times(file_split)
                        if elm[0].eval() not in search_adict:
                            if not file_split[0] in folder_adict:
                                print_times("From folder...")
                                is_sq, return_file, dif_files = self.issequence(file_split[0],
                                                                                self.TypeFit(file_split[1]))
                                folder_adict[file_split[0]] = dif_files
                                # print_times(return_file)
                            else:
                                print_times("From list...")
                                is_sq, return_file, dif_files = self.issequence(file_split[0],
                                                                                self.TypeFit(file_split[1]),
                                                                                folder_adict[file_split[0]])
                                folder_adict[file_split[0]] = dif_files
                                # print_times(return_file)
                            ##
                            Normal_adict, Miss_adict = self.AssetEdit(elm, is_sq, return_file, file_split[0],
                                                                      Normal_adict, Miss_adict)
                            search_adict[elm[0].eval()] = [is_sq, return_file]
                        else:
                            ## find it in search_adict
                            returns = search_adict[elm[0].eval()]
                            Normal_adict, Miss_adict = self.AssetEdit(elm, returns[0], returns[1], file_split[0],
                                                                      Normal_adict, Miss_adict)

                    elif elm[-1] == None or elm[-1] == "":
                        ## check types
                        print(elm)
                        if elm[0].name() in self._typelist:
                            pass
                    else:
                        print("-" * 80)
                        print("DO FILT")
                        print_times(elm)
            print_times("Ebd: {0}".format(elm[0]))

        print("self.runcode-----%s" % self.runcode)
        self.asset_adict = {"Normal": Normal_adict, "Miss": Miss_adict, "camera": self.CheckCamera()}
        self.tips_adict = {}
        # print('>>>>>>Normal_adict: %s' % Normal_adict)

        self.TipsInfo()
        self.WriteFile(self.asset_adict, self._args.asset, 'json')
        self.WriteFile(self.tips_adict, self._args.tips, 'json')
        self.WriteFile({"is_success": 1}, self._args.success)

    def TypeFit(self, filename):
        if not self.runcode:
            self.runend = True
            sys.exit(886)
        for stype in self.sequence_type_list:
            if stype in filename:
                filename = filename.replace(stype, "1001")
        return filename

    def TipsInfo(self):
        if not self.runcode:
            self.runend = True
            sys.exit(886)
        ## {"Miss":{"Node":["filename",[elm]]}}
        info_temp = ''
        print("=" * 25 + " Tips Info " + "=" * 25)
        if "Miss" in self.asset_adict:
            keyword_war = '50001'  ### just for warnning
            infos_list = []
            if len(self.asset_adict["Miss"]):
                for nodes in self.asset_adict["Miss"]:
                    asset_type_adict = self.asset_adict["Miss"][nodes]
                    print("Nodes: %s" % nodes)
                    print("File name: %s" % asset_type_adict[0])
                    if len(asset_type_adict[-1]) == 1:
                        print("Miss file: %s" % asset_type_adict[-1][0])
                        info_temp = "Nodes: %s  File name: %s  miss file: %s " % (
                        nodes, asset_type_adict[0], asset_type_adict[-1][0])
                    elif len(asset_type_adict[-1]) > 1:
                        print("Miss files: %s" % str(asset_type_adict[-1]))
                        info_temp = "Nodes: %s  File name: %s  miss file: %s " % (
                        nodes, asset_type_adict[0], str(asset_type_adict[-1]))
                    infos_list.append(info_temp)
                    print("-" * 80)
            if len(infos_list):
                self.tips_adict[keyword_war] = infos_list

        if "camera" in self.asset_adict:
            print("-" * 23 + " Cameras Info " + "-" * 23)
            keyword_err = '50002'  ### just for error
            keyword_war = '50003'  ### camera warnning
            infos_list_err = []
            infos_list_war = []
            if "diff" in self.asset_adict["camera"]:
                print(">> With diffrence values")
                for elm in self.asset_adict["camera"]["diff"]:
                    print(elm)
                    if len(elm) > 1:
                        base_input = elm.keys()[0]
                        for key in elm.keys():
                            if len(key) < len(base_input): base_input = key
                        print("Base Nodes: %s  file: %s " % (base_input, elm[base_input][0]))
                        info_temp = ("Nodes with diffrence file val: %s " % base_input)
                        for nd in elm:
                            if nd != base_input:
                                if elm[nd][1] == 0:
                                    print("Nodes with diffrence file val: %s " % nd)
                                    print("File: %s " % elm[nd][0])
                    else:
                        print("Errors...(camera checks) ")
                    infos_list_war.append(info_temp)
                    print("-" * 80)
                print("-" * 80)
                if len(infos_list_war):
                    self.tips_adict[keyword_war] = infos_list_war

            if "miss" in self.asset_adict["camera"]:
                for elm in self.asset_adict["camera"]["miss"]:
                    if len(elm) > 1:
                        print(">> Camera did not exist.")
                        print("Nodes: %s  \nMiss: %s" % (elm.keys()[0], elm[elm.keys()[0]][0]))
                        info_temp = ("Nodes: %s  Miss: %s" % (elm.keys()[0], elm[elm.keys()[0]][0]))
                    else:
                        print(">> Camera did not exist(the cam path which in the rop node is not exist).")
                        print("Nodes: %s  \nMiss: This camera is not in the .hip file." % elm.keys()[0])
                        info_temp = ("Nodes: %s  Miss: This camera is not in the .hip file." % elm.keys()[0])
                    infos_list_err.append(info_temp)
                    print("-" * 80)

            if "normal" in self.asset_adict["camera"]:
                if len(self.asset_adict["camera"]["normal"]):
                    if len(infos_list_err):
                        if len(infos_list_war):
                            self.tips_adict[keyword_war].extend(infos_list_err)
                        else:
                            self.tips_adict[keyword_war] = infos_list_err
                else:
                    if len(infos_list_err):
                        self.tips_adict[keyword_err] = infos_list_err
            else:
                if len(infos_list_war):
                    self.tips_adict[keyword_err] = infos_list_war
                    if len(infos_list_err):
                        self.tips_adict[keyword_err].extend(infos_list_err)
                elif len(infos_list_err):
                    self.tips_adict[keyword_err] = infos_list_err

    def analy_info(self):
        if not self.runcode:
            self.runend = True
            sys.exit(886)
        print_times("Analysis start...")
        rop_node, geo_node, geo_nodes, rop_nodes = list(), list(), dict(), dict()
        geo_info, geo_flag_count = "", 0
        rop_info, rop_flag_count = "", 0
        distributedsim_node = []
        info = ''
        i = 0
        print_times("Searching Geometrry Rops...")

        for obj in hou.node('/').allSubChildren():
            obj_path = obj.path().replace('\\', '/')
            obj_type_name = obj.type().name()
            render_node = hou.node(obj_path)
            if obj_type_name in ['geometry', 'rop_geometry']:
                if render_node.parm("execute"):
                    print_times("Geometry ROP: %s" % render_node)
                    if geo_flag_count > 0:
                        geo_info += '\n'
                    geo_info += obj_path
                    geo_nodes["node"] = obj_path
                    geo_info += '|' + str(obj.evalParm('f1'))
                    geo_info += '|' + str(obj.evalParm('f2'))
                    geo_info += '|' + str(obj.evalParm('f3'))
                    pass_frame = str(int(obj.evalParm('f3'))) if int(obj.evalParm('f3')) > 0 else "1"
                    geo_nodes["frames"] = "%s-%s[%s]" % (
                        str(int(obj.evalParm('f1'))), str(int(obj.evalParm('f2'))), pass_frame)
                    geo_info += '|' + '0'
                    geo_nodes["option"] = '0'
                    geo_nodes["render"] = "0"
                    geo_node.append(geo_nodes.copy())
                    geo_flag_count += 1
        print_times("Total Render Nodes: %s" % geo_flag_count)
        # print ("geo_node----%s" % geo_node)
        # print ("rop_node----%s" % rop_node)

        print_times("Searching distributedsim Nodes...")
        simu_cunt = 0
        for obj in hou.node('/').allSubChildren():
            nodes = {}  ## {"node":"","frames":"","option":""}
            objPath = obj.path()
            objPath = objPath.replace('\\', '/')
            objTypeName = obj.type().name()
            if objTypeName in ['hq_sim']:
                sim_rop_Node = hou.node(objPath)
                output_dirver = hou.node(sim_rop_Node.parm("hq_driver").eval())

                if output_dirver.parm("execute"):
                    print_times(" distributedsim Nodes: %s" % objPath)
                    print_times(" output_dirver : %s" % output_dirver)
                    nodes["node"] = objPath
                    nodes["output_driver"] = sim_rop_Node.parm("hq_driver").eval()
                    nodes["output_file"] = output_dirver.parm("sopoutput").eval()
                    nodes["sliceType"] = sim_rop_Node.parm("slice_type").evalAsString()
                    print_times("sliceType: %s" % nodes["sliceType"])
                    nodes["simControlName"] = sim_rop_Node.parm("hq_sim_controls").evalAsString()
                    print_times("simControlName: %s" % nodes["simControlName"])

                    if nodes["sliceType"] == "particle":
                        nodes["num_slices"] = str(sim_rop_Node.parm("num_slices").eval())
                    elif nodes["sliceType"] == "volume":
                        nodes["slicediv"] = sim_rop_Node.parmTuple("slicediv").eval()
                        nodes["num_slices"] = str(nodes["slicediv"][0] * nodes["slicediv"][1] * nodes["slicediv"][2])
                    elif nodes["sliceType"] == "cluster":
                        nodes["simControlName"] = sim_rop_Node.parm("hq_cluster_node").evalAsString()
                        nodes["num_slices"] = str(hou.node(nodes["simControlName"]).parm("num_clusters").eval())
                        nodes["cluster_filter"] = hou.node(nodes["simControlName"]).parm("cluster_filter").eval()
                    else:
                        print_times("%s  不支持，请修改文件.." % nodes["sliceType"])
                        print_times("this %s sliceType is %s ,it's not supported" % (nodes["node"], nodes["sliceType"]))
                        self.tips_adict["50007"] = "this %s sliceType is %s ,it's not supported" % (
                            nodes["node"], nodes["sliceType"])

                    if int(nodes["num_slices"]) > 16:
                        print_times("this %s num_slices is  %s ,it's more than 16,please change .." % (
                        nodes["node"], nodes["num_slices"]))
                        self.tips_adict["50008"] = "this %s num_slices is  %s ,it's more than 16,please change .." % (
                        nodes["node"], nodes["num_slices"])

                    pass_frame = str(int(output_dirver.evalParm('f3'))) if int(
                        output_dirver.evalParm('f3')) > 0 else "1"
                    nodes["frames"] = "%s-%s[%s]" % (
                    str(int(output_dirver.evalParm('f1'))), str(int(output_dirver.evalParm('f2'))), pass_frame)
                    nodes["option"] = '1'
                    nodes["render"] = "0"
                    distributedsim_node.append(nodes)
                    i += 1
                    simu_cunt += 1
        print_times("Total distributedsim Nodes: %s" % simu_cunt)

        # geo_node.extend(distributedsim_node)

        print_times("Searching Render ROPS ...")
        rop_cunt = 0
        for obj in hou.node('/').allSubChildren():
            nodes = {}
            objPath = obj.path()
            objPath = objPath.replace('\\', '/')
            objTypeName = obj.type().name()

            if objTypeName in ['ifd', 'arnold', 'Redshift_ROP', 'ris::22', 'baketexture::3.0']:
                render_rop_Node = hou.node(objPath)
                print_times("   Render ROP: %s" % render_rop_Node)
                if i > 0: info += '\n'
                info += objPath
                info += '|' + str(obj.evalParm('f1'))
                info += '|' + str(obj.evalParm('f2'))
                info += '|' + str(obj.evalParm('f3'))
                info += '|' + '-1'

                nodes["node"] = objPath
                pass_frame = str(int(obj.evalParm('f3'))) if int(obj.evalParm('f3')) > 0 else "1"
                nodes["frames"] = "%s-%s[%s]" % (str(int(obj.evalParm('f1'))), str(int(obj.evalParm('f2'))), pass_frame)
                cam_type = {"Redshift_ROP": "RS_renderCamera", "ifd": "camera", "arnold": "camera", "ris::22": "camera",
                            'baketexture::3.0': "camera"}
                nodes["camera"] = obj.parm(cam_type[objTypeName]).eval()
                try:
                    if hou.node(nodes["camera"]) != None:
                        if hou.node(nodes["camera"]).type().name() != "cam":
                            for cam_i in hou.node(nodes["camera"]).allSubChildren():
                                if cam_i.type().name() == "cam":
                                    print("Camera path: " + str(cam_i.path()))
                                    nodes["width"] = str(cam_i.parm("resx").eval())
                                    nodes["height"] = str(cam_i.parm("resy").eval())
                        else:
                            nodes["width"] = str(hou.node(nodes["camera"]).parm("resx").eval())
                            nodes["height"] = str(hou.node(nodes["camera"]).parm("resy").eval())
                    else:
                        nodes["width"] = ''
                        nodes["height"] = ''
                except:
                    nodes["width"] = ''
                    nodes["height"] = ''

                nodes["option"] = '-1'
                nodes["render"] = "0" if obj.isBypassed() else "1"
                rop_node.append(nodes)
                i += 1
                rop_cunt += 1
        print_times("Total Render ROPs: %s" % rop_cunt)

        # default frames
        default_frames = "%s-%s[%s]" % (
        str(hou.hscriptExpression("$FSTART")), str(hou.hscriptExpression("$FEND")), "1.0")
        scene_info = {"geo_node": geo_node, "rop_node": rop_node, "distributedsim_node": distributedsim_node}
        # scene_info = {"geo_node": geo_node, "rop_node": rop_node}
        self.task_adict["scene_info"] = scene_info
        print("scene_info----%s" % self.task_adict["scene_info"])
        print("self._args.task----%s" % self._args.task)
        self.WriteFile(self.task_adict, self._args.task, 'json')

        print_times("Analysis end...")

    def CheckCamera(self):
        if not self.runcode:
            self.runend = True
            sys.exit(886)
        print_times("CheckCamera start...")
        ropnodes = self.task_adict["scene_info"]["rop_node"]
        camera_adict = {}
        if len(ropnodes):
            cam_normal = []
            cam_diff = []
            cam_miss = []

            for elm in ropnodes:
                n = hou.node(elm["node"])
                cam = None
                for i in n.parms():
                    if i.name() == "camera":
                        cam = n.parm("camera").eval()
                    elif i.name() == "RS_renderCamera":
                        cam = n.parm("RS_renderCamera").eval()

                if hou.node(cam):
                    ## exist
                    print_times("abc_find start...")
                    returns = self.abc_find(cam)
                    if returns[0] == 'normal':
                        print("Normal abc cameras")
                        cam_normal.append(returns[1])
                    elif returns[0] == 'diff':
                        print("Diffrence abc cameras")
                        cam_diff.append(returns[1])
                    elif returns[0] == 'miss':
                        print("Miss abc cameras")
                        cam_miss.append(returns[1])
                    else:
                        print("This camera is in the .hip file.")
                        cam_normal.append({cam: "exist"})
                else:
                    ## not exist
                    print("This camera is not in the .hip file.")
                    cam_miss.append({cam: "notexist"})
            if len(cam_normal): camera_adict["normal"] = cam_normal
            if len(cam_diff): camera_adict["diff"] = cam_diff
            if len(cam_miss): camera_adict["miss"] = cam_miss
        print("camera_adict---%s" % camera_adict)
        return camera_adict

    @staticmethod
    def abc_find(path=""):
        if not HoudiniAnalyse.runcode:
            HoudiniAnalyse.runend = True
            sys.exit(886)
        print("abc_find is working")
        result = True
        return_key = 'notfit'
        temp_adict = {}
        print("path----%s" % path)
        if path != "":
            cam_pl = path.split("/")
            print("len(cam_pl)----%s" % len(cam_pl))
            if len(cam_pl) > 0:
                node_pre = ""
                i = 0
                n_types = ["alembicarchive", "alembicxform", "cam"]
                pathval = {}
                index = 1
                type_abc = False
                first_key = ""
                for elm in cam_pl:
                    if not elm:
                        node_pre += "/" + elm
                        if hou.node(node_pre).type().name() in n_types:
                            if index == 1:
                                if hou.node(node_pre).type().name() == "alembicarchive":
                                    type_abc = True
                                    first_key = node_pre
                            if type_abc == True:
                                p_val = hou.node(node_pre).parm("fileName").eval()
                                pathval[node_pre] = p_val
                            index += 1
                print("len(pathval)----%s" % len(pathval))
                if len(pathval) > 2:
                    vals = pathval[first_key]
                    abc_base = False if not os.path.exists(vals) else True
                    same_p = True
                    keys = None
                    temp_adict = {}
                    return_key = 'normal'
                    for elm in pathval:
                        diff_path = []
                        if not pathval[elm] == vals:
                            if not os.path.exists(pathval[elm]):
                                same_p = False
                                diff_path.append(pathval[elm])
                                diff_path.append(0)  ## whether if the same file with the first file in
                                diff_path.append("notexist")
                            else:
                                same_p = False
                                diff_path.append(pathval[elm])
                                diff_path.append(0)
                                diff_path.append("exist")
                            temp_adict[elm] = diff_path

                        else:
                            if not os.path.exists(pathval[elm]):
                                diff_path.append(pathval[elm])
                                diff_path.append(1)
                                diff_path.append("notexist")
                            else:
                                diff_path.append(pathval[elm])
                                diff_path.append(1)
                                diff_path.append("exist")
                            temp_adict[elm] = diff_path
                    if abc_base:
                        if same_p:
                            return_key = 'normal'
                        else:
                            return_key = 'diff'
                    else:
                        return_key = 'miss'

        return return_key, temp_adict

    # @staticmethod
    def AssetEdit(self, nodeTurp, is_sq, fileadict, file_path, Normal_adict, Miss_adict):
        if not HoudiniAnalyse.runcode:
            HoudiniAnalyse.runend = True
            sys.exit(886)
        if is_sq == 0:
            print("0 is sequence")
            ## {"abc":[["abc.0001.exr","abc.0002.exr"..."abc.0010.exr"],1,10,4,abc.$F4.exr]}
            file_temp = []
            instancepath_list = []
            for elm in fileadict[fileadict.keys()[0]][0]:
                file_temp.append("%s/%s" % (file_path.replace("\\", "/"), elm))
            # print(file_temp)
            node_path = nodeTurp[0].node().path()
            hou.setUpdateMode(hou.updateMode.AutoUpdate)
            if nodeTurp[0].name() in ['file', 'fileName']:
                try:
                    pointAttrib_list = [x.name() for x in hou.node(node_path).geometry().pointAttribs()]
                    if "instancepath" in pointAttrib_list:
                        points = hou.node(node_path).geometry().iterPoints()
                        for point in points:
                            instancepath = point.attribValue("instancepath")
                            instancepath_list.append(instancepath)
                except Exception as e:
                    print('>>>>>>Error: %s' % e)
            instancepath_list = list(set(instancepath_list))
            hou.setUpdateMode(hou.updateMode.Manual)
            print('>>>>>>instancepath_list len : %s' % len(instancepath_list))

            file_in_ass = self.get_ass_assets(nodeTurp)

            if node_path not in Normal_adict:
                file_temp = list(set(file_temp))
                Normal_adict[node_path] = [nodeTurp[-1], file_temp]
                if len(instancepath_list) > 0:
                    i = 1
                    for instancepath in instancepath_list:
                        index_key = '%s/point_%s' % (node_path, i)
                        if os.path.exists(instancepath):
                            Normal_adict[index_key] = [nodeTurp[-1], [instancepath]]
                        else:
                            Miss_adict[index_key] = [nodeTurp[-1], [instancepath]]
                        i += 1

                if len(file_in_ass) > 0:
                    i = 1
                    for in_ass in file_in_ass:
                        index_key = '%s/in_ass_%s' % (node_path, i)
                        if os.path.exists(in_ass):
                            Normal_adict[index_key] = [nodeTurp[-1], [in_ass]]
                        else:
                            Miss_adict[index_key] = [nodeTurp[-1], [in_ass]]
                        i += 1
            else:
                file_temp = list(set(file_temp))
                Normal_adict[node_path][-1].extend(file_temp)
                if len(instancepath_list) > 0:
                    i = 1
                    for instancepath in instancepath_list:
                        index_key = '%s/point_%s' % (node_path, i)
                        if os.path.exists(instancepath):
                            Normal_adict[index_key][-1].extend([instancepath])
                        else:
                            Miss_adict[index_key][-1].extend([instancepath])
                        i += 1

                if len(file_in_ass) > 0:
                    i = 1
                    for in_ass in file_in_ass:
                        index_key = '%s/in_ass_%s' % (node_path, i)
                        if os.path.exists(in_ass):
                            Normal_adict[index_key][-1].extend([in_ass])
                        else:
                            Miss_adict[index_key][-1].extend([in_ass])
                        i += 1

        elif is_sq == 1:
            # print("1 not sequence")
            Fs_list = ["$F", "$F2", "$F3", "$F4", "$F5"]
            node_path = nodeTurp[0].node().path()
            file_temp = "%s/%s" % (file_path.replace("\\", "/"), fileadict)
            ## -----------------------------------------------------------
            ## if its a list type
            for elm in Fs_list:
                if elm in nodeTurp[-1]:
                    if node_path not in Miss_adict:
                        Miss_adict[node_path] = [nodeTurp[-1], [file_temp]]
                    else:
                        Miss_adict[node_path][-1].extend([file_temp])
            ## ------------------------------------------------------------
            instancepath_list = []
            hou.setUpdateMode(hou.updateMode.AutoUpdate)
            if nodeTurp[0].name() in ['file', 'fileName']:
                try:
                    pointAttrib_list = [x.name() for x in hou.node(node_path).geometry().pointAttribs()]
                    if "instancepath" in pointAttrib_list:
                        points = hou.node(node_path).geometry().iterPoints()
                        for point in points:
                            instancepath = point.attribValue("instancepath")
                            instancepath_list.append(instancepath)
                except Exception as e:
                    print('>>>>>>Error: %s' % e)
            instancepath_list = list(set(instancepath_list))
            hou.setUpdateMode(hou.updateMode.Manual)
            print('>>>>>>instancepath_list len : %s' % len(instancepath_list))

            file_in_ass = self.get_ass_assets(nodeTurp)

            if node_path not in Normal_adict:
                Normal_adict[node_path] = [nodeTurp[-1], [file_temp]]
                if len(instancepath_list) > 0:
                    i = 1
                    for instancepath in instancepath_list:
                        index_key = '%s/point_%s' % (node_path, i)
                        if os.path.exists(instancepath):
                            Normal_adict[index_key] = [nodeTurp[-1], [instancepath]]
                        else:
                            Miss_adict[index_key] = [nodeTurp[-1], [instancepath]]
                        i += 1

                if len(file_in_ass) > 0:
                    i = 1
                    for in_ass in file_in_ass:
                        index_key = '%s/in_ass_%s' % (node_path, i)
                        if os.path.exists(in_ass):
                            Normal_adict[index_key] = [nodeTurp[-1], [in_ass]]
                        else:
                            Miss_adict[index_key] = [nodeTurp[-1], [in_ass]]
                        i += 1
            else:
                Normal_adict[node_path][-1].extend([file_temp])
                if len(instancepath_list) > 0:
                    i = 1
                    for instancepath in instancepath_list:
                        index_key = '%s/point_%s' % (node_path, i)
                        if os.path.exists(instancepath):
                            Normal_adict[index_key][-1].extend([instancepath])
                        else:
                            Miss_adict[index_key][-1].extend([instancepath])
                        i += 1

                if len(file_in_ass) > 0:
                    i = 1
                    for in_ass in file_in_ass:
                        index_key = '%s/in_ass_%s' % (node_path, i)
                        if os.path.exists(in_ass):
                            Normal_adict[index_key][-1].extend([in_ass])
                        else:
                            Miss_adict[index_key][-1].extend([in_ass])
                        i += 1

        elif is_sq == 2:
            print("2 file not exist")
            node_path = nodeTurp[0].node().path()
            file_temp = "%s/%s" % (file_path.replace("\\", "/"), fileadict)
            if node_path not in Miss_adict:
                Miss_adict[node_path] = [nodeTurp[-1], [file_temp]]
            else:
                # print(Miss_adict[node_path])
                Miss_adict[node_path][-1].extend([file_temp])

        elif is_sq == 3:
            print_times("error input")

        return Normal_adict, Miss_adict

    @staticmethod
    def get_ass_assets(ass_file):
        ass_assets = []
        ass_path = ass_file[0].eval()
        if not os.path.exists(ass_path):
            return []
        if ass_path.endswith(".gz"):
            try:
                fp = gzip.open(ass_path)
            except:
                print("the file %s unable to read!" % ass_path)
                return []
        else:
            try:
                fp = open(ass_path, "r")
            except:
                print("the file %s unable to read!" % ass_path)
                return []
        if ass_file[0].name() == 'ar_filename':
            for line in fp:
                if line.startswith(" filename ", 0, 10):
                    path = line.split(' ')[-1].split('"')[1]
                    ass_assets.append(path)

        ass_assets = list(set(ass_assets))
        return ass_assets

    @staticmethod
    def isFile(pathvale):
        if not HoudiniAnalyse.runcode:
            HoudiniAnalyse.runend = True
            sys.exit(886)
        isFilepath = False
        persent = 0
        drive_spl = os.path.splitdrive(pathvale)
        ext_spl = os.path.splitext(pathvale)
        along_spl = os.path.split(pathvale)
        if pathvale.replace("\\", "/").startswith("//"): persent += 7
        if len(drive_spl[0]) and len(drive_spl[-1]): persent += 7
        if "/" in along_spl[0].replace("\\", "/"):
            persent += 4
            ss = re.findall("[/*,//]", ext_spl[0].replace("\\", "/"))
            if len(ss) > 1: persent += 1
        if len(ext_spl[-1]): persent += 5
        if "$HIP/" in pathvale.replace("\\", "/"): persent += 7
        if persent > 9: isFilepath = True

        # print("persent",persent)
        # print(drive_spl)
        # print(ext_spl)
        # print(along_spl)

        return isFilepath

    @staticmethod
    def get_encode(encode_str):
        _dcode_list = [sys.getfilesystemencoding(), "utf-8", "gb18030", "ascii", "gbk", "gb2312"]
        if isinstance(encode_str, unicode):
            return "unicode"
        else:
            for code in _dcode_list:
                try:
                    encode_str.decode(code)
                    return code
                except:
                    pass

    @classmethod
    def str_to_unicode(cls, encode_str):
        if encode_str == None or encode_str == "" or encode_str == 'Null' or encode_str == 'null':
            encode_str = ""
            return encode_str
        elif isinstance(encode_str, unicode):
            return encode_str
        else:
            code = cls.get_encode(encode_str)
            return encode_str.decode(code)

    @classmethod
    def issequence(cls, dirt='', filename='', adict_in=[]):
        if not cls.runcode:
            cls.runend = True
            sys.exit(886)
        ## is_sequence: 0 is sequence; 1 not sequence; 2 file not exist; 3 error
        is_sequence = 1
        print_times("Start ssq.{0}&&{1}".format(dirt, filename), "debug")
        if filename != "":
            sequence_adict = {}
            maby_sequence = True
            dif_list = []
            maby_sequence, split_str, num = cls.getnumber(filename)
            print_times("{0} {1} {2}".format(maby_sequence, split_str, num), "debug")
            All_files = os.listdir(dirt) if not len(adict_in) and os.path.exists(dirt) else adict_in
            if maby_sequence:
                sequence_list = []
                for elm in All_files:
                    _maby_sequence, _split_str, _num = cls.getnumber(elm)
                    # print_times("elms {0} {1} {2} {3}".format(elm,_maby_sequence,_split_str,_num),"debug")
                    if _maby_sequence:
                        elm_split = elm.split(_split_str)
                        filename_list = filename.split(split_str)
                        if filename_list[0] == elm_split[0] and elm_split[-1] == filename_list[-1]:
                            if elm not in sequence_list: sequence_list.append(elm)
                        else:
                            dif_list.append(elm)
                    else:
                        dif_list.append(elm)
                if len(sequence_list) > 2:
                    is_sequence = 0
                    i = 0
                    seq_name = ''
                    seq_len = 0
                    min_num = 0
                    max_num = 0
                    first_elm = ''
                    for elm in sequence_list:
                        num = cls.getnumber(elm)[2]
                        if i == 0:
                            min_num = int(num)
                            first_elm = elm
                        if i == len(sequence_list) - 1: seq_len_end = len(num)
                        if int(num) < min_num:
                            min_num = int(num)
                            first_elm = elm
                        if int(num) > max_num: max_num = int(num)
                        i += 1
                    # print("%s sequence from %d to %d"%(seq_name,min_num,max_num))
                    maybes, split_str_1, num_1 = cls.getnumber(first_elm)
                    seq_name = first_elm.split(split_str_1)[0]
                    end_with = first_elm.split(split_str_1)[-1]
                    if len(num_1) > 1:
                        file_replace_name = seq_name + split_str_1.replace(num_1, "$F%d" % len(num_1)) + end_with
                    else:
                        file_replace_name = seq_name + split_str_1.replace(num_1, "$F") + end_with

                    """ put into adict """
                    """ {"abc":[["abc.0001.exr","abc.0002.exr"..."abc.0010.exr"],1,10,4,abc.$F4.exr]} """
                    sequence_adict[seq_name] = [sequence_list, min_num, max_num, len(num_1), file_replace_name]
                    return is_sequence, sequence_adict, dif_list
                else:
                    maby_sequence = False
            if not maby_sequence:
                file_path = os.path.abspath(os.path.join(dirt, filename))
                if os.path.exists(file_path):
                    ### exist ,but not a sequence
                    if len(adict_in):
                        if filename in adict_in:
                            adict_in.remove(filename)
                        dif_list.extend(adict_in)
                    else:
                        if filename in All_files:
                            All_files.remove(filename)
                        dif_list.extend(All_files)
                    return is_sequence, filename, dif_list
                else:
                    # print("this file is not exist.")
                    if len(adict_in):
                        dif_list.extend(adict_in)
                    else:
                        dif_list.extend(All_files)
                    return 2, filename, dif_list
        else:
            print_times("Please set the filename for this function.")
            return 3, "Please set the filename for this function.", []

    @staticmethod
    def getnumber(filename=''):
        if not HoudiniAnalyse.runcode:
            HoudiniAnalyse.runend = True
            sys.exit(886)
        maby_sequence = True
        split_str = ''
        num = ''
        with_num = re.findall("\d+", filename)
        if len(with_num) > 0:
            num = with_num[-1]
            num_len = len(with_num[-1])
            if ("." + with_num[-1] + ".") in filename:
                split_str = "." + with_num[-1] + "."
            elif (with_num[-1] + ".") in filename:
                split_str = with_num[-1] + "."
            else:
                maby_sequence = False
                # print("Not sequence")
        else:
            maby_sequence = False
            # print("Without Numbers")
        return maby_sequence, split_str, num

    @staticmethod
    def WriteFile(info={}, file="", types='txt'):
        if not HoudiniAnalyse.runcode:
            HoudiniAnalyse.runend = True
            sys.exit(886)
        if types == 'txt':
            with codecs.open(file, "w", 'utf-8') as f:
                info = str(info)
                f.write(info)
                f.close()
        elif types == 'json':
            with codecs.open(file, "w", 'utf-8') as f:
                json.dump(info, f, indent=2)
                f.close()
        print_times("Infomations write to %s" % file)


def set_runcode():
    f = "C:/temp/deg.mc"
    f_linux = "/tmp/deg.mc"
    if os.path.exists(f) or os.path.exists(f_linux):
        HoudiniAnalyse.runcode = False


def set_args():
    parser = argparse.ArgumentParser()
    parser.add_argument('-project', type=str, required=True, help='.hip file to load')
    parser.add_argument('-task', type=str, required=True, help='the task file .json path')
    parser.add_argument('-asset', type=str, required=True, help='the asset file .json path')
    parser.add_argument('-tips', type=str, required=True, help='the tips file .json path')
    parser.add_argument('-success', type=str, required=False, help='whether analyse success')
    args = parser.parse_args()
    # print(args)
    return args


def analyse_main(args):
    houdini_analyse_obj = HoudiniAnalyse(args)
    print_times('Load hip file start...')
    try:
        houdini_analyse_obj.loadhipfile()
    except:
        print_times('Load hip ignore Errors.')
    print_times('Load hip file end.')
    set_runcode()
    houdini_analyse_obj.analy_info()
    houdini_analyse_obj.GetAssets()
    print(HoudiniAnalyse.runcode, HoudiniAnalyse.runend)


def print_times(info, ext="info"):
    if ext == "info":
        print(str(info))
    else:
        print("[debug]{0}".format(str(info)))


if __name__ == "__main__":
    print("\n")
    print("*" * 80)
    print("Python version: %s" % sys.version)
    print("\n")
    command_line_params = set_args()
    analyse_main(command_line_params)
