from __future__ import print_function

import os
import sys
# import commands
import subprocess


class SourceSync(object):
    def __init__(self, dir1="", dir2=""):
        self.rootp1 = None
        self.rootp2 = None
        self.diff_list = []
        self.new_list1 = []
        self.new_list2 = []
        self.ext_list = [".txt", ".xrc", ".py", ".ini", ".amt", ".xml", ".cc", ".hh", ".i", ".rst", ".cpp", ".h", ".html", ".sh"]
        self.inc_list = ["Makefile", "depend"]

        self.init(dir1, dir2)

    def init(self, dir1="", dir2=""):
        if dir1 == "" or (not os.path.exists(dir1)):
            self.rootp1 = os.path.join(os.environ["HOME"], "mlf090626")
        else:
            self.rootp1 = dir1

        if dir2 == "" or (not os.path.exists(dir2)):
            self.rootp2 = os.path.join(os.environ["HOME"], "svn_chopper/chopper/mlf")
        else:
            self.rootp2 = dir2

        self.diff_list = []
        self.new_list1 = []
        self.new_list2 = []

        results1 = self._walklist(self.rootp1)
        results2 = self._walklist(self.rootp2)
        results1.sort()
        results2.sort()

        # check whether files of dir1 exist in dir2
        mv_flag = 0
        for item in results1:
            path = os.path.join(self.rootp2, item)
            if not os.path.exists(path):
                self.new_list1.append([item, mv_flag])

        # check whether files of dir2 exist in dir1
        mv_flag = 0
        for item in results2:
            path = os.path.join(self.rootp1, item)
            if not os.path.exists(path):
                self.new_list2.append([item, mv_flag])

        # do diff command on files in dir1 and dir2
        mv_flag = 1
        remove_list = []
        for item in self.new_list1:
            remove_list.append(item[0])

        for item in results1:
            if (not (item in remove_list)):
                path1 = os.path.join(self.rootp1, item)
                path2 = os.path.join(self.rootp2, item)
                cmd = "diff " + path1 + " " + path2
                diff_msg = subprocess.getoutput(cmd)

                if diff_msg != "":
                    try:
                        uni_msg = unicode(diff_msg, "utf-8")
                    except:
                        print("### ERROR : {} : Diff messages = {}".format(item, diff_msg))
                        uni_msg = diff_msg
                    self.diff_list.append([item, mv_flag, uni_msg])

    def _walklist(self, in_path):
        all_path = []
        file_list = []
        path_list = []
        ill_path = []
        for a, b, c in os.walk(in_path):
            if a.find(".svn") != -1:
                continue
            for a_c in c:
                if os.path.splitext(a_c)[1] in self.ext_list:
                    all_path.append(os.path.join(a, a_c))
                    pp = a.split(in_path)[1]
                    if len(pp) != 0:
                        if pp[0] == '/':
                            pp = pp[1:]

                    path_list.append(pp)
                    file_list.append(a_c)
                else:
                    isNotFound = True
                    for inc in self.inc_list:
                        if a_c.find(inc) >= 0:
                            all_path.append(os.path.join(a, a_c))
                            pp = a.split(in_path)[1]
                            if len(pp) != 0:
                                if pp[0] == '/':
                                    pp = pp[1:]
                            path_list.append(pp)
                            file_list.append(a_c)
                            isNotFound = False
                    if isNotFound:
                        ill_path.append(os.path.join(a, a_c))

        ret = []
        for items in zip(path_list, file_list):
            ret.append(os.path.join(items[0], items[1]))
        return ret

        """
        for items in zip(path_list,file_list):
            print ">> "+items[0]+"   "+items[1]
        print "-------"
        for item in ill_path:
            print item
        """

    def show(self, index=-1):
        if index == -1:
            print("=============================================================")
            print("     Unique Files in {}".format(self.rootp1))
            print("-------------------------------------------------------------")
            for i in range(len(self.new_list1)):
                print("{0:>3} | {1:<60} | {2:<1} |".format(i, self.new_list1[i][0], self.new_list1[i][1]))

            print("=============================================================")
            print("     Unique Files in {:^20}".format(self.rootp2))
            print("-------------------------------------------------------------")
            for i in range(len(self.new_list2)):
                print("{0:>3} | {1:<60} | {2:<1} |".format(i, self.new_list2[i][0], self.new_list2[i][1]))

            print("=============================================================")
            print("     Different Files ")
            print("-------------------------------------------------------------")
            for i in range(len(self.diff_list)):
                print("{0:>3} | {1:<60} | {2:<1} |".format(i, self.diff_list[i][0], self.diff_list[i][1]))

        else:
            self.show_comment(index)

    def show_comment(self, index):
        print("=================================")
        path1 = os.path.join(self.rootp1, self.diff_list[index][0])
        path2 = os.path.join(self.rootp2, self.diff_list[index][0])
        print("diff {} {}".format(path1, path2))

        print(self.diff_list[index][2])

    def removeDiff(self, index):
        self._changeFlag(self.diff_list, index, 0)

    def removeNew1(self, index):
        self._changeFlag(self.new_list1, index, 0)

    def removeNew2(self, index):
        self._changeFlag(self.new_list2, index, 0)

    def addDiff(self, index):
        self._changeFlag(self.diff_list, index, 1)

    def addNew1(self, index):
        self._changeFlag(self.new_list1, index, 1)

    def addNew2(self, index):
        self._changeFlag(self.new_list2, index, 1)

    def _changeFlag(self, list, index, flag):
        if flag in [0, 1]:
            if isinstance(index, int):
                list[index][1] = flag
            if isinstance(index, list):
                for i in index:
                    list[i][1] = flag

    def update1to2(self):
        print("Copying files in {} into {}.".format(self.rootp1, self.rootp2))
        item_list = self.new_list1 + self.diff_lsit
        for item in item_list:
            if item[1] != 0:
                cmd = "cp " + os.path.join(self.rootp1, item[0]) + " " + os.path.join(self.rootp2, item[0])
                print("CMD>>{}".format(cmd))
                os.system(cmd)

    def update2to1(self):
        print("Copying files in {} into {}.".format(self.rootp2, self.rootp1))
        item_list = self.new_list1 + self.diff_lsit
        for item in item_list:
            if item[1] != 0:
                cmd = "cp " + os.path.join(self.rootp1, item[0]) + " " + os.path.join(self.rootp2, item[0])
                print("CMD>>{}".format(cmd))
                os.system(cmd)


if __name__ == '__main__':
    import os
    import sys

    if len(sys.argv) == 1:
        rootp = os.path.join(os.environ["HOME"], "mlf090626")
        repop = os.path.join(os.environ["HOME"], "svn_chopper/chopper/mlf")
    if len(sys.argv) == 2:
        rootp = sys.argv[1]
        repop = os.path.join(os.environ["HOME"], "svn_chopper/chopper/mlf")
    if len(sys.argv) == 3:
        rootp = sys.argv[1]
        repop = sys.argv[2]
    print("rootp,repop={}, {}".format(rootp, repop))
    if (os.path.exists(rootp)) and (os.path.exists(repop)):
        ss = SourceSync(rootp, repop)
        ss.show()
    else:
        print("Path is invalid.")
