#!/usr/bin/env python

from __future__ import print_function, unicode_literals

import argparse
import difflib
import logging
import os
import subprocess
import sys
import tempfile

logging.basicConfig(format='%(message)s', level=logging.INFO)


class RoundTripTask(object):
    def __init__(self, input_filename, action, swift_syntax_test,
                 skip_bad_syntax):
        assert action == '-round-trip-parse' or action == '-round-trip-lex'
        assert type(input_filename) == unicode
        assert type(swift_syntax_test) == str

        assert os.path.isfile(input_filename), \
            "Input file {} is not accessible!".format(input_filename)
        assert os.path.isfile(swift_syntax_test), \
            "{} tool is not accessible!".format(swift_syntax_test)
        self.input_filename = input_filename
        self.action = action
        self.swift_syntax_test = swift_syntax_test
        self.skip_bad_syntax = skip_bad_syntax
        self.returncode = None
        self.stdout = None
        self.stderr = None

    @property
    def test_command(self):
        return [self.swift_syntax_test, self.action,
                '-input-source-filename', self.input_filename]

    def run(self):
        command = self.test_command
        logging.debug(' '.join(command))
        self.output_file = tempfile.NamedTemporaryFile('w', delete=False)
        self.stderr_file = tempfile.NamedTemporaryFile('w', delete=False)

        process = subprocess.Popen(command, stdout=self.output_file,
                                   stderr=self.stderr_file)
        process.wait()
        self.returncode = process.returncode

        self.output_file.close()
        self.stderr_file.close()

        with open(self.output_file.name, 'r') as stdout_in:
            self.stdout = stdout_in.read()
        with open(self.stderr_file.name, 'r') as stderr_in:
            self.stderr = stderr_in.read()

        os.remove(self.output_file.name)
        os.remove(self.stderr_file.name)

        if self.returncode != 0:
            if self.skip_bad_syntax:
                logging.warning('---===WARNING===--- Lex/parse had error'
                                ' diagnostics, so not diffing. Skipping'
                                ' this file due to -skip-bad-syntax.')
                logging.error(' '.join(command))
                return None
            else:
                logging.error('---===ERROR===--- Lex/parse had error'
                              ' diagnostics, so not diffing.')
                logging.error(' '.join(command))
                logging.error(self.stdout)
                logging.error(self.stderr)
                raise RuntimeError()

        contents = ''.join(map(lambda l: l.decode('utf-8', errors='replace'),
                               open(self.input_filename).readlines()))
        stdout_contents = self.stdout.decode('utf-8', errors='replace')

        if contents == stdout_contents:
            return None

        lines = difflib.unified_diff(contents, stdout_contents,
                                     fromfile=self.input_filename,
                                     tofile='-')
        diff = '\n'.join(line for line in lines)
        return diff if diff else None


def swift_files_in_dir(d):
    swift_files = []
    for root, dirs, files in os.walk(d):
        for basename in files:
            if not basename.decode('utf-8').endswith('.swift'):
                continue
            abs_file = os.path.abspath(os.path.join(root, basename))
            swift_files.append(abs_file)
    return swift_files


def run_task(task):
    try:
        diff = task.run()
        if diff is not None:
            logging.error('---===ERROR===--- Diff failed!')
            logging.error(' '.join(task.test_command))
            logging.error(diff)
            logging.error('')
            return True
    except RuntimeError as e:
        logging.error(e.message)
        return True
    return False


def main():
    tool_description = '''
Checks for round-trip lex/parse/print compatibility.

Swift's syntax representation should be "full-fidelity", meaning that there is
a perfect representation of what is in the source. When printing a syntax tree
to a file, that file should be identical to the file that was
originally parsed.

This driver invokes swift-syntax-test using -round-trip-lex and
-round-trip-parse on .swift files and .swift files in directories.
'''
    parser = argparse.ArgumentParser(description=tool_description)
    parser.add_argument('--directory', '-d', action='append',
                        dest='input_directories', default=[],
                        help='Add a directory, searching for .swift files'
                             ' within')
    parser.add_argument('--file', '-f', action='append',
                        dest='individual_input_files', default=[],
                        help='Add an individual file to test')
    parser.add_argument('--swift-syntax-test', '-t', required=True,
                        dest='tool_path',
                        help='Absolute path to the swift-syntax-test tool')
    parser.add_argument('--skip-bad-syntax',
                        action='store_true',
                        default=False,
                        help="Skip files that caused lex or parse diagnostics"
                             " to be emitted")

    args = parser.parse_args()

    dir_listings = [swift_files_in_dir(d) for d in args.input_directories]
    all_input_files = [filename for dir_listing in dir_listings
                       for filename in dir_listing]
    all_input_files += args.individual_input_files
    all_input_files = [f.decode('utf-8') for f in all_input_files]

    if len(all_input_files) == 0:
        logging.error('No input files!')
        sys.exit(1)

    if not os.path.isfile(args.tool_path):
        raise RuntimeError("Couldn't find swift-syntax-test at {}"
                           .format(args.tool_path))

    lex_tasks = [RoundTripTask(filename, '-round-trip-lex', args.tool_path,
                               args.skip_bad_syntax)
                 for filename in all_input_files]
    parse_tasks = [RoundTripTask(filename, '-round-trip-parse', args.tool_path,
                                 args.skip_bad_syntax)
                   for filename in all_input_files]

    failed = reduce(lambda a, b: a or b,
                    map(run_task, lex_tasks + parse_tasks))
    sys.exit(1 if failed else 0)


if __name__ == '__main__':
    main()
