#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import sys
import subprocess 
import datetime
import argparse
import commands


git_repo_path = os.path.abspath(subprocess.check_output(['git', 'rev-parse', '--show-toplevel']).strip())


def splitall(path):
    allparts = []
    while 1:
        parts = os.path.split(path)
        if parts[0] == path:  # sentinel for absolute paths
            allparts.insert(0, parts[0])
            break
        elif parts[1] == path: # sentinel for relative paths
            allparts.insert(0, parts[1])
            break
        else:
            path = parts[0]
            allparts.insert(0, parts[1])
    return allparts
    
    
def process(filepath):

    short_filepath = filepath[len(git_repo_path):]
    if short_filepath.startswith(os.sep):
       short_filepath = short_filepath[len(os.sep):] 
    
    filename = os.path.basename(filepath)
    if filename.startswith('.'):
        return
    file_ext = os.path.splitext(filename)[1]
    if file_ext in ('.swift'):
        env_copy = os.environ.copy()
        env_copy["SCRIPT_INPUT_FILE_COUNT"] = "1"
        env_copy["SCRIPT_INPUT_FILE_0"] = '%s' % ( short_filepath, )
        lint_output = subprocess.check_output(['swiftlint', 'autocorrect', '--use-script-input-files'], env=env_copy)
        print lint_output
        try:
            lint_output = subprocess.check_output(['swiftlint', 'lint', '--use-script-input-files'], env=env_copy)
        except subprocess.CalledProcessError, e:
            lint_output = e.output
        print lint_output
    
    with open(filepath, 'rt') as f:
        text = f.read()
    original_text = text
    
    lines = text.split('\n')
    while lines and lines[0].startswith('//'):
        lines = lines[1:]
    text = '\n'.join(lines)
    text = text.strip()

    header = '''//
//  Copyright (c) %s Open Whisper Systems. All rights reserved.
//

''' % ( 
    datetime.datetime.now().year,
    )
    text = header + text + '\n'

    if original_text == text:
        return
    
    print 'Updating:', short_filepath
    
    with open(filepath, 'wt') as f:
        f.write(text)


def should_ignore_path(path):
    ignore_paths = [
        os.path.join(git_repo_path, '.git')
    ]
    for ignore_path in ignore_paths:
        if path.startswith(ignore_path):
            return True
    for component in splitall(path):
        if component.startswith('.'):
            return True
        if component.endswith('.framework'):
            return True
        if component in ('Pods', 'ThirdParty', 'Carthage',):
            return True                
        
    return False
    
    
def process_if_appropriate(filepath):
    filename = os.path.basename(filepath)
    if filename.startswith('.'):
        return
    file_ext = os.path.splitext(filename)[1]
    if file_ext not in ('.h', '.hpp', '.cpp', '.m', '.mm', '.pch', '.swift'):
        return
    if should_ignore_path(filepath):
        return
    process(filepath)

    
if __name__ == "__main__":
    
    parser = argparse.ArgumentParser(description='Precommit script.')
    parser.add_argument('--all', action='store_true', help='process all files in or below current dir')
    args = parser.parse_args()
    
    if args.all:
        for rootdir, dirnames, filenames in os.walk(git_repo_path):
            for filename in filenames:
                file_path = os.path.abspath(os.path.join(rootdir, filename))
                process_if_appropriate(file_path)
    else:
        filepaths = []
        
        # Staging
        output = commands.getoutput('git diff --cached --name-only --diff-filter=ACMR')
        filepaths.extend([line.strip() for line in output.split('\n')])

        # Working
        output = commands.getoutput('git diff --name-only --diff-filter=ACMR')
        filepaths.extend([line.strip() for line in output.split('\n')])
        
        # Only process each path once.
        filepaths = sorted(set(filepaths))

        for filepath in filepaths:
            filepath = os.path.abspath(os.path.join(git_repo_path, filepath))
            process_if_appropriate(filepath)

    print 'git clang-format...'
    print commands.getoutput('git clang-format')
