#!/usr/bin/python3

import os
import subprocess
import getopt
import sys
import filecmp
import shutil

CRED = '\033[91m'
CEND = '\033[0m'
CCYAN = '\033[96m'
CBLUE = '\033[94m'
CGREEN = '\033[92m'

def _usage():
   """ print command line options """
   print("usage sync-file.py -h/--help -c/--compare-path=<path> -p/--print file\n"\
      "file                       # input fil , left side of diff\n"\
      "-c / -compare-path= <path> # <path> to directory to file-sync\n"\
      "-p / --print               # print only, dont do any actual sync\n"\
      "-h / --help                # Help ")

def _get_last_mod_date(file):
   try: 
      return int(round(os.path.getmtime(file)))
   except FileNotFoundError as err:
      print(err)
      return None

def _diff_files(src_file, dst_file):
   diff_cmd = shutil.which('meld')

   if diff_cmd != None:
      try:
         subprocess.run([diff_cmd, src_file, dst_file])
      except:
         print("can't start diff tool")
   else:
      print("can't find diff tool")

def _conditional_copy_file(src_file, dst_file):
   if _ask():
      os.system('cp ' + src_file + ' ' + dst_file) 
   
def _ask():
   try: 
      answer = lower(input('\tproceed with copy? [Y/n]: '))
   except EOFError:
      return False

   ret_val = False
   if answer == '' or answer == 'y' or answer == 'yes':
      ret_val =  True
   
   return ret_val

def main():
   try:
      opts, args = getopt.getopt(sys.argv[1:], "dphc:", ["diff", "compare-path=", "print", "help"])
   except getopt.GetoptError as err:
      # print help information and exit:
      print(err) # will print something like "option -a not recognized"
      sys.exit(2)

   file_diff = False
   dry_run = False
   compare_path = "."

   ### parse input command line
   for o, a in opts:
      if o in ("-h", "--help"):
         _usage()
         sys.exit()
      elif o in ("-p", "--print"):
         dry_run = True
      elif o in ("-c", "--compare-path"):
         compare_path = a
      elif o in ("-d", "--diff"):
         file_diff = True
      else:
         print(o, a)
         assert False, "unhandled option"

   for left_file in args:
      #left_file contain the full path + file name. pick out filename only and apply the compare_path
      right_file = compare_path + '/' + left_file #os.path.basename(left_file)
      #print(left_file)
      #print(right_file)
      left_file_exists = os.path.isfile(left_file)
      right_file_exists = os.path.isfile(right_file)
      
      if not left_file_exists:
         print(CRED + '\tno such file... ' + left_file + CEND)
      if not right_file_exists:
         print(CRED + '\tno such file... ' + right_file + CEND)

         if not dry_run:
            _conditional_copy_file(left_file, right_file)

      if left_file_exists and right_file_exists:
         #if left and right are different, decide which file is to be copied
         if not filecmp.cmp(left_file, right_file):
            left_file_mod_time = _get_last_mod_date(left_file)
            right_file_mod_time = _get_last_mod_date(right_file)

            if left_file_mod_time < right_file_mod_time:  # left file newer
               src_file = right_file
               dst_file = left_file
               color = CBLUE     
            else:                                         # right file newer
               src_file = left_file
               dst_file = right_file
               color = CCYAN

            print(color + '\t' + src_file + ' is newer than ' + dst_file + '...' + CEND)

            if not dry_run:
               _conditional_copy_file(src_file, dst_file)

            if file_diff:
               _diff_files(left_file, right_file)


         else:
            print(CGREEN + '\t' + os.path.basename(left_file) + ' same same...' + CEND)


if __name__ == '__main__':
   main()
