# Copyright 2021 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import contextlib
import difflib
import filecmp
import os
import shutil
import tempfile
import unittest

from json5_generator import Json5File, Writer


@contextlib.contextmanager
def tmp_dir():
    tmp = tempfile.mkdtemp()
    try:
        yield tmp
    finally:
        shutil.rmtree(tmp)


def path_to_test_file(*path):
    return os.path.join(os.path.dirname(__file__), 'tests', *path)


def diff(filename1, filename2):
    with open(filename1) as file1:
        file1_lines = file1.readlines()
    with open(filename2) as file2:
        file2_lines = file2.readlines()

    # Use Python's difflib module so that diffing works across platforms
    return ''.join(difflib.context_diff(file1_lines, file2_lines))


def is_identical_file(reference_filename, output_filename):
    reference_basename = os.path.basename(reference_filename)

    if not os.path.isfile(reference_filename):
        print 'Missing reference file!'
        print '(if adding new test, update reference files)'
        print reference_basename
        print
        return False

    if not filecmp.cmp(reference_filename, output_filename):
        # cmp is much faster than diff, and usual case is "no difference",
        # so only run diff if cmp detects a difference
        print 'FAIL: %s' % reference_basename
        print diff(reference_filename, output_filename)
        return False

    return True


def compare_output_dir(reference_dir, output_dir):
    """
    Compares output files in both reference_dir and output_dir.

    Note: this function ignores subdirectory content in both reference
    dir and output_dir.

    Note: reference_dir should have all ref files ending with .ref suffix.
    '.ref' suffix is added to bypass code formatter on reference files.

    :returns {bool}: Whether files in output dir matches files in ref dir
    """
    ref_content = {
        f[:-4]
        for f in os.listdir(reference_dir) if f.endswith('.ref')
    }
    output_content = set(os.listdir(output_dir))

    if ref_content != output_content:
        print 'Output files does not match.'
        print 'Following files are extra: {}'.format(output_content -
                                                     ref_content)
        print 'Following files are missing: {}'.format(ref_content -
                                                       output_content)
        return False

    for file_name in ref_content:
        ref_file = os.path.join(reference_dir, file_name) + '.ref'
        output_file = os.path.join(output_dir, file_name)

        if os.path.isdir(ref_file) and os.path.isdir(output_file):
            continue
        elif os.path.isdir(ref_file) or os.path.isdir(output_file):
            return False
        elif not is_identical_file(ref_file, output_file):
            return False

    return True


class WriterTest(unittest.TestCase):
    def _test_writer(self, writer_class, json5_files, reference_dir):
        """
        :param writer_class {Writer}: a subclass to Writer
        :param json5_files {List[str]}: json5 test input files
        :param reference_dir {str}: directory to expected output files
        """
        with tmp_dir() as tmp:
            writer = writer_class(json5_files, tmp)
            writer.write_files(tmp)
            writer.cleanup_files(tmp)

            self.assertTrue(compare_output_dir(reference_dir, tmp))
