#!/usr/bin/env python
# -*- coding: utf-8 -*-
#-----------------------------------------------------------------------------
# Copyright (C) 2008-2013 Fabrice HARROUET (ENIB)
#
# Permission to use, copy, modify, distribute and sell this software
# and its documentation for any purpose is hereby granted without fee,
# provided that the above copyright notice appear in all copies and
# that both that copyright notice and this permission notice appear
# in supporting documentation.
# The author makes no representations about the suitability of this
# software for any purpose.
# It is provided "as is" without express or implied warranty.
#-----------------------------------------------------------------------------

import sys
import os
import subprocess
import traceback

showUsage=False
showDiff=False
quickDiff=False
base1=None
base2=None

def dirDiff(b1,b2,cmpFiles):
  sys.stdout.write('\n')
  sys.stdout.write('~~~~~~~~ CHECKING %s AGAINST %s ~~~~~~~~\n'%(b2,b1))
  sys.stdout.write('\n')
  for (dirpath,dirnames,filenames) in os.walk(b1):
    relPath=dirpath[len(b1):]
    for i in sorted(dirnames):
      d=os.path.join(relPath,i)
      d2=os.path.join(b2,d)
      if not os.path.isdir(d2):
        sys.stdout.write('IN %s MISSING DIRECTORY %s\n'%(b2,d))
        dirnames.remove(i)
    for i in sorted(filenames):
      f=os.path.join(relPath,i)
      f2=os.path.join(b2,f)
      if not os.path.exists(f2):
        sys.stdout.write('IN %s MISSING FILE %s\n'%(b2,f))
      elif cmpFiles:
        f1=os.path.join(b1,f)
        diff=False
        try:
          if os.path.getsize(f1)!=os.path.getsize(f2):
            diff=True
          elif not quickDiff:
            nullDev=open('/dev/null','w')
            p=subprocess.Popen(['cmp','-s',f1,f2],
                               stdout=nullDev,stderr=nullDev)
            p.wait()
            if p.returncode!=0:
              diff=True
        except:
          diff=True
        if diff:
          sys.stdout.write('DIFF %s %s\n'%(f1,f2))
          if showDiff:
            try:
              subprocess.Popen(['tkdiff',f1,f2]).wait()
            except:
              pass

for i in sys.argv[1:]:
  if i=='-s':
    showDiff=True
  elif i=='-q':
    quickDiff=True
  elif os.path.isdir(i):
    if base1 is None:
      base1=i
    elif base2 is None:
      base2=i
    else:
      showUsage=True
  else:
    showUsage=True
if base1 is None or base2 is None:
  showUsage=True
if showUsage:
  sys.stdout.write('usage: %s [-s] [-q] dir1 dir2\n'%sys.argv[0])
  sys.stdout.write('       -s: show differences in files (with tkdiff)\n')
  sys.stdout.write('       -q: quick comparison (file sizes only)\n')
  sys.exit(1)
if not base1.endswith(os.path.sep):
  base1+=os.path.sep
if not base2.endswith(os.path.sep):
  base2+=os.path.sep

dirDiff(base1,base2,False)

dirDiff(base2,base1,True)

#-----------------------------------------------------------------------------
