#!/usr/bin/python

import hashlib
import operator
import os
import shutil
import stat
import subprocess
import sys
import tempfile


def rel_to_abs(rel_path):
    return os.path.join(script_path, rel_path)


java_bin_path = os.getenv('JAVA_HOME', '')
if java_bin_path:
    java_bin_path = os.path.join(java_bin_path, 'bin')

main_class = 'org.chromium.devtools.jsdoc.JsDocValidator'
jar_name = 'jsdoc_validator.jar'
hashes_name = 'hashes'
src_dir = 'src'
script_path = os.path.dirname(os.path.abspath(__file__))
closure_jar_relpath = os.path.join('..', 'closure', 'compiler.jar')
src_path = rel_to_abs(src_dir)
hashes_path = rel_to_abs(hashes_name)


def get_file_hash(file, blocksize=65536):
    sha = hashlib.sha256()
    buf = file.read(blocksize)
    while len(buf) > 0:
        sha.update(buf)
        buf = file.read(blocksize)
    return sha.hexdigest()


def traverse(hasher, path):
    abs_path = rel_to_abs(path)
    info = os.lstat(abs_path)
    quoted_name = repr(path.replace('\\', '/'))
    if stat.S_ISDIR(info.st_mode) and not os.path.basename(path).startswith('.'):
        hasher.update('d ' + quoted_name + '\n')
        for entry in sorted(os.listdir(abs_path)):
            traverse(hasher, os.path.join(path, entry))
    elif stat.S_ISREG(info.st_mode) and path.endswith('.java'):
        hasher.update('r ' + quoted_name + ' ')
        hasher.update(str(info.st_size) + ' ')
        with open(abs_path, 'Ur') as file:
            f_hash = get_file_hash(file)
            hasher.update(f_hash + '\n')


def get_src_dir_hash(dir):
    sha = hashlib.sha256()
    traverse(sha, dir)
    return sha.hexdigest()


def get_actual_hashes():
    hashed_files = [(jar_name, True)]
    hashes = {}
    for (file_name, binary) in hashed_files:
        try:
            hash = get_file_hash(open(file_name, 'rb' if binary else 'r'))
            hashes[file_name] = hash
        except IOError:
            hashes[file_name] = '0'
    hashes[src_dir] = get_src_dir_hash(src_dir)
    return hashes


def get_expected_hashes():
    try:
        with open(hashes_path, 'r') as file:
            return {
                file_name: hash
                for (file_name, hash) in [(name.strip(), hash.strip()) for (hash, name) in [line.split(' ', 1) for line in file]]
            }
    except:
        return None


def run_and_communicate(command, error_template):
    proc = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True)
    proc.communicate()
    if proc.returncode:
        print >> sys.stderr, error_template % proc.returncode
        sys.exit(proc.returncode)


def build_artifacts():
    print 'Compiling...'
    java_files = []
    for root, dirs, files in sorted(os.walk(src_path)):
        for file_name in files:
            if file_name.endswith('.java'):
                java_files.append(os.path.join(root, file_name))

    bin_path = tempfile.mkdtemp()
    manifest_file = tempfile.NamedTemporaryFile(mode='wt', delete=False)
    try:
        manifest_file.write('Class-Path: %s\n' % closure_jar_relpath)
        manifest_file.close()
        javac_path = os.path.join(java_bin_path, 'javac')
        javac_command = '%s -target 7 -source 7 -d %s -cp %s %s' % (javac_path, bin_path, rel_to_abs(closure_jar_relpath),
                                                                    ' '.join(java_files))
        run_and_communicate(javac_command, 'Error: javac returned %d')

        print 'Building jar...'
        artifact_path = rel_to_abs(jar_name)
        jar_path = os.path.join(java_bin_path, 'jar')
        jar_command = '%s cvfme %s %s %s -C %s .' % (jar_path, artifact_path, manifest_file.name, main_class, bin_path)
        run_and_communicate(jar_command, 'Error: jar returned %d')
    finally:
        os.remove(manifest_file.name)
        shutil.rmtree(bin_path, True)


def update_hashes():
    print 'Updating hashes...'
    with open(hashes_path, 'w') as file:
        file.writelines(['%s %s\n' % (hash, name) for (name, hash) in get_actual_hashes().iteritems()])


def hashes_modified():
    expected_hashes = get_expected_hashes()
    if not expected_hashes:
        return [('<no expected hashes>', 1, 0)]
    actual_hashes = get_actual_hashes()
    results = []
    for name, expected_hash in expected_hashes.iteritems():
        actual_hash = actual_hashes.get(name)
        if expected_hash != actual_hash:
            results.append((name, expected_hash, actual_hash))
    return results


def help():
    print 'usage: %s [option]' % os.path.basename(__file__)
    print 'Options:'
    print '--force-rebuild: Rebuild classes and jar even if there are no source file changes'
    print '--no-rebuild: Do not rebuild jar, just update hashes'


def main():
    no_rebuild = False
    force_rebuild = False

    if len(sys.argv) > 1:
        if sys.argv[1] == '--help':
            help()
            return
        no_rebuild = sys.argv[1] == '--no-rebuild'
        force_rebuild = sys.argv[1] == '--force-rebuild'

    if not hashes_modified() and not force_rebuild:
        print 'No modifications found, rebuild not required.'
        return
    if not no_rebuild:
        build_artifacts()

    update_hashes()
    print 'Done.'


if __name__ == '__main__':
    main()
