#!/usr/bin/env python

from __future__ import print_function, unicode_literals

import argparse
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
                ]

    @property
    def diff_command(self):
        return ['/usr/bin/diff', '-u', self.input_filename, '-']

    def diff(self):
        logging.debug(' '.join(self.diff_command))
        diff = subprocess.Popen(self.diff_command, stdin=subprocess.PIPE,
                stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        stdout, stderr = diff.communicate(self.stdout)
        if diff.returncode != 0:
            return stdout
        assert stdout == ''
        assert stderr == ''
        return None

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

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

        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()

        self.output_file.flush()
        self.stderr_file.flush()

        try:
            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()
        finally:
            self.output_file.close()
            self.stderr_file.close()

        diff = self.diff()
        return diff

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 and b,
            map(run_task, lex_tasks + parse_tasks))
    sys.exit(1 if failed else 0)

if __name__ == '__main__':
    main()
