#!/usr/bin/env python2.7
# Copyright 2020 The Fuchsia 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 filecmp
import imp
import json
import os
import shutil
import subprocess
import sys
import tarfile
import tempfile
import unittest

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
GENERATE_FILEPATH = os.path.join(SCRIPT_DIR, 'generate.py')
generate = imp.load_source('generate', GENERATE_FILEPATH)

TMP_DIR_NAME = tempfile.mkdtemp(prefix='tmp_unittest_%s_' % 'GNGenerateTest')
TMP_ARCH_DIR = tempfile.mkdtemp(prefix='tmp_unittest_%s_' % 'GNGenArchiveTest')
TMP_ARCHIVE_PATH = os.path.join(TMP_ARCH_DIR, 'gn.tar.gz')

EXPECTED_PREBUILTS = {
    'aemu': 'git_revision:a123456789abcdef0123456789abcdef01234567',
    'grpcwebproxy': 'git_revision:b123456789abcdef0123456789abcdef01234567',
    'device_launcher': 'g3-revision:vdl_fuchsia_20200819_RC00',
}


class GNGenerateTest(unittest.TestCase):

    def setUp(self):
        # make sure TMP_DIR_NAME is empty
        if os.path.exists(TMP_DIR_NAME):
            shutil.rmtree(TMP_DIR_NAME)
        os.makedirs(TMP_DIR_NAME)

    def tearDown(self):
        if os.path.exists(TMP_DIR_NAME):
            shutil.rmtree(TMP_DIR_NAME)

    def testEmptyArchive(self):
        # Run the generator.
        generate.main(
            [
                "--output",
                TMP_DIR_NAME,
                "--output-archive",
                TMP_ARCHIVE_PATH,
                "--directory",
                os.path.join(SCRIPT_DIR, 'testdata'),
                "--jiri-manifest",
                os.path.join(
                    SCRIPT_DIR, 'testdata', '.jiri_root', 'update_history',
                    'latest'),
            ])
        self.verify_contents(TMP_DIR_NAME)
        # verify tarball
        tar = tarfile.open(TMP_ARCHIVE_PATH)
        tar.extractall(TMP_ARCH_DIR)
        tar.close()
        os.remove(TMP_ARCHIVE_PATH)
        self.verify_manifest(TMP_ARCH_DIR)

    def testPrebuilts(self):
        INPUT_PREBUILTS = generate.EXTRA_PREBUILTS
        prebuilt_results = generate.get_prebuilts(
            INPUT_PREBUILTS,
            os.path.join(
                SCRIPT_DIR, 'testdata', '.jiri_root', 'update_history',
                'latest'))
        if cmp(prebuilt_results, EXPECTED_PREBUILTS) != 0:
            self.fail(
                "Expected output %s but returned %s instead" %
                (EXPECTED_PREBUILTS, prebuilt_results))

    def verify_contents(self, outdir):
        # update_golden.py doesn't copy bin and build subdirectories because we
        # don't want duplicates of things in base, so ignore them here too.
        dcmp = filecmp.dircmp(
            outdir, os.path.join(SCRIPT_DIR, 'golden'), ignore=['bin', 'build'])
        self.verify_contents_recursive(dcmp)

        # Special case: outdir/build/test_targets.gni is a generated file.
        generated_file = os.path.join(outdir, 'build', 'test_targets.gni')
        golden_file = os.path.join(
            SCRIPT_DIR, 'golden', 'build', 'test_targets.gni')
        if not filecmp.cmp(generated_file, golden_file, False):
            self.fail(_gen_diff(generated_file, golden_file))

        # Special case: Check the prebuilts *.version files generated from the jiri manifest
        for prebuilt, version in EXPECTED_PREBUILTS.items():
            in_path = os.path.join(outdir, 'bin', prebuilt + '.version')
            with open(in_path, 'r') as in_file:
                in_version = in_file.read().strip()
                if in_version != version:
                    self.fail(
                        "Generated %s in %s does not match expected %s" %
                        (in_version, in_path))

    def verify_contents_recursive(self, dcmp):
        """Recursively checks for differences between two directories.

        Fails if the directories do not appear to be deeply identical in
        structure and content.

        Args:
            dcmp (filecmp.dircmp): A dircmp of the directories.
        """
        if dcmp.left_only or dcmp.right_only:
            self.fail("Generated SDK does not match golden files. " \
                "You can run ./update_golden.py to update them.\n" \
                "Only in {}:\n{}\n\n" \
                "Only in {}:\n{}\n\n"
                .format(dcmp.left, dcmp.left_only, dcmp.right, dcmp.right_only))
        elif dcmp.diff_files:
            # Show a diff of the culprit files. Need to run diff for each pair.
            diff_result = ''
            for file in dcmp.diff_files:
                diff_result += _gen_diff(
                    os.path.join(dcmp.left, file),
                    os.path.join(dcmp.right, file))
            self.fail("Generated SDK does not match golden files. " \
                "You can run ./update_golden.py to update them.\n" \
                "Left : {}\n" \
                "Right: {}\n" \
                "Different files: {}\n" \
                "{}"
                .format(dcmp.left, dcmp.right, dcmp.diff_files, diff_result))

        for sub_dcmp in dcmp.subdirs.values():
            self.verify_contents_recursive(sub_dcmp)

    def verify_manifest(self, sdk_dir):
        """Read the manifest and verify all files are referenced."""
        metafile = os.path.join(sdk_dir, 'meta', 'manifest.json')
        fileset = set()
        fileset.add(os.path.relpath(metafile, sdk_dir))
        with open(metafile, 'r') as input:
            metadata = json.load(input)
        for atom in metadata['parts']:
            fileset.add(atom['meta'])
            with open(os.path.join(sdk_dir, atom['meta']), 'r') as input:
                atom_meta = json.load(input)
                fileset.update(self.get_atom_files(atom_meta))
        self.assertTrue(len(fileset) != 0)
        # walk the sdk_dir matching the files in the set.
        for dir_name, _, file_list in os.walk(sdk_dir):
            for f in file_list:
                found_file = os.path.relpath(os.path.join(dir_name, f), sdk_dir)
                self.assertIn(found_file, fileset)
                fileset.remove(found_file)
        self.assertTrue(
            len(fileset) == 0, "Files missing from manifest: %s" % str(fileset))

    def get_atom_files(self, atom):
        files = set()
        if 'headers' in atom:
            files.update(atom['headers'])
        if 'sources' in atom:
            files.update(atom['sources'])
        if 'data' in atom:
            files.update(atom['data'])
        if 'docs' in atom:
            files.update(atom['docs'])
        if 'files' in atom:
            files.update(atom['files'])
        if 'resources' in atom:
            files.update(atom['resources'])
        if 'target_files' in atom:
            for a in atom['target_files']:
                files.update(atom['target_files'][a])
        if 'binaries' in atom:
            for a in atom['binaries']:
                arch_atom = atom['binaries'][a]
                if 'debug' in arch_atom:
                    files.add(arch_atom['debug'])
                if 'dist' in arch_atom:
                    files.add(arch_atom['dist'])
                if 'link' in arch_atom:
                    files.add(arch_atom['link'])
                if type(arch_atom) is list:
                    files.update(arch_atom)
        if 'versions' in atom:
            for a in atom['versions']:
                arch_atom = atom['versions'][a]
                if 'debug_libs' in arch_atom:
                    files.update(arch_atom['debug_libs'])
                if 'dist_libs' in arch_atom:
                    files.update(arch_atom['dist_libs'])
                if 'headers' in arch_atom:
                    files.update(arch_atom['headers'])
                if 'link_libs' in arch_atom:
                    files.update(arch_atom['link_libs'])

        return files


def _gen_diff(a, b):
    cmd_args = ['diff', '-U', '2', a, b]
    pipe = subprocess.Popen(cmd_args, stdout=subprocess.PIPE)
    out, err = pipe.communicate()
    return "diff of '{}':\n{}\n".format(os.path.basename(a), out)


def TestMain():
    unittest.main()


if __name__ == '__main__':
    TestMain()
