#!/usr/bin/env python3
# Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.
"""Top-level presubmit script for Dart.

See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
for more details about the presubmit API built into gcl.
"""

import datetime
import importlib.util
import importlib.machinery
import os
import os.path
from typing import Callable
import scm
import subprocess
import tempfile
import platform

USE_PYTHON3 = True


def is_cpp_file(path):
    return path.endswith('.cc') or path.endswith('.h')


def is_dart_file(path):
    return path.endswith('.dart')


def get_old_contents(input_api, path):
    local_root = input_api.change.RepositoryRoot()
    upstream = input_api.change._upstream
    return scm.GIT.Capture(['show', upstream + ':' + path],
                           cwd=local_root,
                           strip_out=False)


def files_to_check_for_format(input_api, extension, exclude_folders):
    files = []
    exclude_folders += [
        "pkg/front_end/testcases/", "pkg/front_end/parser_testcases/"
    ]
    for git_file in input_api.AffectedTextFiles():
        local_path = git_file.LocalPath()
        if not local_path.endswith(extension):
            continue
        if any([local_path.startswith(f) for f in exclude_folders]):
            continue
        files.append(git_file)
    return files


def _CheckFormat(input_api, identification, extension, windows,
                 hasFormatErrors: Callable[[str, list, str],
                                           bool], exclude_folders):
    files = files_to_check_for_format(input_api, extension, exclude_folders)
    if not files:
        return []

    # Check for formatting errors in bulk first. This is orders of magnitude
    # faster than checking file-by-file on large changes with hundreds of files.
    if not hasFormatErrors(filenames=[f.AbsoluteLocalPath() for f in files]):
        return []

    print("Formatting errors found, comparing against old versions.")
    unformatted_files = []
    for git_file in files:
        filename = git_file.AbsoluteLocalPath()
        if hasFormatErrors(filename=filename):
            old_version_has_errors = False
            try:
                path = git_file.LocalPath()
                if windows:
                    # Git expects a linux style path.
                    path = path.replace(os.sep, '/')
                if hasFormatErrors(contents=get_old_contents(input_api, path)):
                    old_version_has_errors = True
            except subprocess.CalledProcessError as e:
                old_version_has_errors = False

            if old_version_has_errors:
                print("WARNING: %s has existing and possibly new %s issues" %
                      (git_file.LocalPath(), identification))
            else:
                unformatted_files.append(filename)

    return unformatted_files


def load_source(modname, filename):
    loader = importlib.machinery.SourceFileLoader(modname, filename)
    spec = importlib.util.spec_from_file_location(modname,
                                                  filename,
                                                  loader=loader)
    module = importlib.util.module_from_spec(spec)
    # The module is always executed and not cached in sys.modules.
    # Uncomment the following line to cache the module.
    # sys.modules[module.__name__] = module
    loader.exec_module(module)
    return module


def _CheckDartFormat(input_api, output_api):
    local_root = input_api.change.RepositoryRoot()
    utils = load_source('utils', os.path.join(local_root, 'tools', 'utils.py'))

    dart = os.path.join(utils.CheckedInSdkPath(), 'bin', 'dart')

    windows = utils.GuessOS() == 'win32'
    if windows:
        dart += '.exe'

    if not os.path.isfile(dart):
        print('WARNING: dart not found: %s' % (dart))
        return []

    def HasFormatErrors(filename: str = None,
                        filenames: list = None,
                        contents: str = None):
        # Don't look for formatting errors in multitests. Since those are very
        # sensitive to whitespace, many cannot be reformatted without breaking
        # them.
        def skip_file(path):
            if path.endswith('_test.dart'):
                with open(path, encoding='utf-8') as f:
                    contents = f.read()
                    if '//#' in contents:
                        return True
            return False

        if filename and skip_file(filename):
            return False

        args = [
            dart,
            'format',
            '--set-exit-if-changed',
            '--output=none',
            '--summary=none',
        ]

        # TODO(https://github.com/dart-lang/sdk/issues/46947): Remove this hack.
        if windows and contents:
            f = tempfile.NamedTemporaryFile(
                encoding='utf-8',
                delete=False,
                mode='w',
                suffix='.dart',
            )
            try:
                f.write(contents)
                f.close()
                args.append(f.name)
                process = subprocess.run(args)
            finally:
                os.unlink(f.name)
        elif contents:
            process = subprocess.run(args, input=contents, text=True)
        elif filenames:
            args += [f for f in filenames if not skip_file(f)]
            process = subprocess.run(args)
        else:
            args.append(filename)
            process = subprocess.run(args)

        # Check for exit code 1 explicitly to distinguish it from a syntax error
        # in the file (exit code 65). The repo contains many Dart files that are
        # known to have syntax errors for testing purposes and which can't be
        # parsed and formatted. Don't treat those as errors.
        return process.returncode == 1

    unformatted_files = _CheckFormat(input_api, "dart format", ".dart", windows,
                                     HasFormatErrors, [])

    if unformatted_files:
        lineSep = " \\\n"
        if windows:
            lineSep = " ^\n"
        return [
            output_api.PresubmitError(
                'File output does not match dart format.\n'
                'Fix these issues with:\n'
                '%s format %s' % (dart, lineSep.join(unformatted_files)))
        ]

    return []


def _CheckStatusFiles(input_api, output_api):
    local_root = input_api.change.RepositoryRoot()
    utils = load_source('utils', os.path.join(local_root, 'tools', 'utils.py'))

    dart = os.path.join(utils.CheckedInSdkPath(), 'bin', 'dart')
    lint = os.path.join(local_root, 'pkg', 'status_file', 'bin', 'lint.dart')

    windows = utils.GuessOS() == 'win32'
    if windows:
        dart += '.exe'

    if not os.path.isfile(dart):
        print('WARNING: dart not found: %s' % dart)
        return []

    if not os.path.isfile(lint):
        print('WARNING: Status file linter not found: %s' % lint)
        return []

    def HasFormatErrors(filename=None, filenames=None, contents=None):
        if filenames:
            # The status file linter doesn't support checking files in bulk.
            # Returning `True` causes `_CheckFormat` to fallback to check
            # formatting file by file below.
            return True
        args = [dart, lint] + (['-t'] if contents else [filename])
        process = subprocess.run(args, input=contents, text=True)
        return process.returncode != 0

    exclude_folders = [
        "pkg/status_file/test/data/",
        "pkg/front_end/",
    ]
    unformatted_files = _CheckFormat(input_api, "status file", ".status",
                                     windows, HasFormatErrors, exclude_folders)

    if unformatted_files:
        normalize = os.path.join(local_root, 'pkg', 'status_file', 'bin',
                                 'normalize.dart')
        lineSep = " \\\n"
        if windows:
            lineSep = " ^\n"
        return [
            output_api.PresubmitError(
                'Status files are not normalized.\n'
                'Fix these issues with:\n'
                '%s %s -w%s%s' % (dart, normalize, lineSep,
                                  lineSep.join(unformatted_files)))
        ]

    return []


def _CheckValidHostsInDEPS(input_api, output_api):
    """Checks that DEPS file deps are from allowed_hosts."""
    # Run only if DEPS file has been modified to annoy fewer bystanders.
    if all(f.LocalPath() != 'DEPS' for f in input_api.AffectedFiles()):
        return []
    # Outsource work to gclient verify
    try:
        input_api.subprocess.check_output(['gclient', 'verify'])
        return []
    except input_api.subprocess.CalledProcessError as error:
        return [
            output_api.PresubmitError(
                'DEPS file must have only dependencies from allowed hosts.',
                long_text=error.output)
        ]


def _CheckLayering(input_api, output_api):
    """Run VM layering check.

  This check validates that sources from one layer do not reference sources
  from another layer accidentally.
  """

    # Run only if .cc or .h file was modified.
    if all(not is_cpp_file(f.LocalPath()) for f in input_api.AffectedFiles()):
        return []

    local_root = input_api.change.RepositoryRoot()
    compiler_layering_check = load_source(
        'compiler_layering_check',
        os.path.join(local_root, 'runtime', 'tools',
                     'compiler_layering_check.py'))
    errors = compiler_layering_check.DoCheck(local_root)
    embedder_layering_check = load_source(
        'embedder_layering_check',
        os.path.join(local_root, 'runtime', 'tools',
                     'embedder_layering_check.py'))
    errors += embedder_layering_check.DoCheck(local_root)
    if errors:
        return [
            output_api.PresubmitError(
                'Layering check violation for C++ sources.',
                long_text='\n'.join(errors))
        ]

    return []


def _CheckClangTidy(input_api, output_api):
    """Run clang-tidy on VM changes."""

    # Only run clang-tidy on linux x64.
    if platform.system() != 'Linux' or platform.machine() != 'x86_64':
        return []

    # Run only for modified .cc or .h files.
    files = []
    for f in input_api.AffectedFiles():
        path = f.LocalPath()
        if is_cpp_file(path) and os.path.isfile(path): files.append(path)

    if not files:
        return []

    args = [
        'tools/sdks/dart-sdk/bin/dart',
        'runtime/tools/run_clang_tidy.dart',
    ]
    args.extend(files)
    stdout = input_api.subprocess.check_output(args).strip()
    if not stdout:
        return []

    return [
        output_api.PresubmitError(
            'The `clang-tidy` linter revealed issues:',
            long_text=stdout)
    ]


def _CheckClangFormat(input_api, output_api):
    """Run clang-format on VM changes."""

    # Only run clang-format on linux x64.
    if platform.system() != 'Linux' or platform.machine() != 'x86_64':
        return []

    # Run only for modified .cc or .h files, except for DEPS changes.
    files = []
    is_deps = False
    for f in input_api.AffectedFiles():
        path = f.LocalPath()
        if path == 'DEPS' and any(
                map(lambda content: 'clang' in content[1],
                    f.ChangedContents())):
            is_deps = True
            break
        if is_cpp_file(path) and os.path.isfile(path):
            files.append(path)

    if is_deps:
        find_args = [
            'find',
            'runtime/',
            '-iname',
            '*.h',
            '-o',
            '-iname',
            '*.cc',
        ]
        files = subprocess.check_output(find_args, text=True).split()

    if not files:
        return []

    args = [
        'buildtools/linux-x64/clang/bin/clang-format',
        '--dry-run',
        '--Werror',
    ]
    args.extend(files)
    stdout = input_api.subprocess.check_output(args).strip()
    if not stdout:
        return []

    return [
        output_api.PresubmitError('The `clang-format` revealed issues:',
                                  long_text=stdout)
    ]


def _CheckAnalyzerFiles(input_api, output_api):
    """Run analyzer checks on source files."""

    # Verify the "error fix status" file.
    code_files = [
        "pkg/analyzer/lib/src/error/error_code_values.g.dart",
        "pkg/linter/lib/src/rules.dart",
    ]

    if any(f.LocalPath() in code_files for f in input_api.AffectedFiles()):
        args = [
            "tools/sdks/dart-sdk/bin/dart",
            "pkg/analysis_server/tool/presubmit/verify_error_fix_status.dart",
        ]
        stdout = input_api.subprocess.check_output(args).strip()
        if not stdout:
            return []

        return [
            output_api.PresubmitError(
                "The verify_error_fix_status Analyzer tool revealed issues:",
                long_text=stdout)
        ]

    # Verify the linter's `example/all.yaml` file.
    if any(f.LocalPath().startswith('pkg/linter/lib/src/rules')
           for f in input_api.AffectedFiles()):
        args = [
            "tools/sdks/dart-sdk/bin/dart",
            "pkg/linter/tool/checks/check_all_yaml.dart",
        ]
        stdout = input_api.subprocess.check_output(args).strip()
        if not stdout:
            return []

        return [
            output_api.PresubmitError(
                "The check_all_yaml linter tool revealed issues:",
                long_text=stdout)
        ]

    # TODO(srawlins): Check more:
    # * "verify_sorted" for individual modified (not deleted) files in
    #   Analyzer-team-owned directories.
    # * "verify_tests" for individual modified (not deleted) test files in
    #   Analyzer-team-owned directories.
    # * Verify that `messages/generate.dart` does not produce different
    #   content, when `pkg/analyzer/messages.yaml` is modified.
    # * Verify that `diagnostics/generate.dart` does not produce different
    #   content, when `pkg/analyzer/messages.yaml` is modified.
    # * Maybe "verify_no_solo" for individual modified (not deleted test files
    #   in Analyzer-team-owned directories.

    # No files are relevant.
    return []


def _CheckTestMatrixValid(input_api, output_api):
    """Run script to check that the test matrix has no errors."""

    def test_matrix_filter(affected_file):
        """Only run test if either the test matrix or the code that
           validates it was modified."""
        path = affected_file.LocalPath()
        return (path == 'tools/bots/test_matrix.json' or
                path == 'tools/validate_test_matrix.dart' or
                path.startswith('pkg/smith/'))

    if len(
            input_api.AffectedFiles(
                include_deletes=False, file_filter=test_matrix_filter)) == 0:
        return []

    command = [
        'tools/sdks/dart-sdk/bin/dart',
        'tools/validate_test_matrix.dart',
    ]
    stdout = input_api.subprocess.check_output(command).strip()
    if not stdout:
        return []
    else:
        return [
            output_api.PresubmitError(
                'The test matrix is not valid:', long_text=stdout)
        ]


def _CheckCopyrightYear(input_api, output_api):
    """Check copyright year in new files."""

    files = []
    year = str(datetime.datetime.now().year)
    for f in input_api.AffectedFiles(include_deletes=False):
        path = f.LocalPath()
        if (is_dart_file(path) or is_cpp_file(path)
           ) and f.Action() == 'A' and os.path.isfile(path):
            with open(path, encoding='utf-8') as f:
                first_line = f.readline()
                if 'Copyright' in first_line and year not in first_line:
                    files.append(path)

    if not files:
        return []

    return [
        output_api.PresubmitPromptWarning(
            'Copyright year for new files should be ' + year + ':\n' +
            '\n'.join(files))
    ]


def _CheckNoNewObservatoryServiceTests(input_api, output_api):
    """Ensures that no new tests are added to the Observatory test suite."""
    files = []

    for f in input_api.AffectedFiles(include_deletes=False):
        path = f.LocalPath()
        if is_dart_file(path) and path.startswith(
                "runtime/observatory/tests/service/") and f.Action(
                ) == 'A' and os.path.isfile(path):
            files.append(path)

    if not files:
        return []

    return [
        output_api.PresubmitError(
            'New VM service tests should be added to pkg/vm_service/test, ' +
            'not runtime/observatory/tests/service:\n' + '\n'.join(files))
    ]


def _CheckDevCompilerSync(input_api, output_api):
    """Make sure that any changes in the original and the temporary forked
    version of the DDC compiler are kept in sync. If a CL touches the
    compiler.dart there should probably be in a change in compiler_new.dart
    as well.
    """
    OLD = "pkg/dev_compiler/lib/src/kernel/compiler.dart"
    NEW = "pkg/dev_compiler/lib/src/kernel/compiler_new.dart"

    files = [git_file.LocalPath() for git_file in input_api.AffectedTextFiles()]

    if (OLD in files and NEW not in files):
        return [
            output_api.PresubmitPromptWarning(
                "Make sure to keep the original and temporary forked versions "
                "of compiler.dart in sync.\n"
                "You may need to copy or adapt changes between these files:\n" +
                "\n".join([OLD, NEW]))
        ]

    return []


def _CheckDartApiWinCSync(input_api, output_api):
    """Ensure that dart_api_win.c is up-to-date."""
    GENERATOR = "runtime/tools/generate_dart_api_win_c.dart"
    DART_API_H = "runtime/include/dart_api.h"
    DART_NATIVe_API_H = "runtime/include/dart_native_api.h"

    files = [git_file.LocalPath() for git_file in input_api.AffectedTextFiles()]

    if (GENERATOR in files or DART_API_H in files or
            DART_NATIVe_API_H in files):
        # Run the generator with `--check-up-to-date` to see if the output is
        # up-to-date.
        args = [
            "tools/sdks/dart-sdk/bin/dart",
            GENERATOR,
            "--check-up-to-date",
        ]
        try:
            subprocess.run(args, check=True)
        except subprocess.CalledProcessError as e:
            return [
                output_api.PresubmitError(
                    f"Make sure to re-run {GENERATOR} when it or its inputs "
                    "change.")
            ]

    return []


def _CommonChecks(input_api, output_api):
    results = []
    results.extend(_CheckValidHostsInDEPS(input_api, output_api))
    results.extend(_CheckDartFormat(input_api, output_api))
    results.extend(_CheckStatusFiles(input_api, output_api))
    results.extend(_CheckLayering(input_api, output_api))
    results.extend(_CheckClangTidy(input_api, output_api))
    results.extend(_CheckClangFormat(input_api, output_api))
    results.extend(_CheckTestMatrixValid(input_api, output_api))
    results.extend(
        input_api.canned_checks.CheckPatchFormatted(input_api, output_api))
    results.extend(_CheckCopyrightYear(input_api, output_api))
    results.extend(_CheckAnalyzerFiles(input_api, output_api))
    results.extend(_CheckNoNewObservatoryServiceTests(input_api, output_api))
    results.extend(_CheckDevCompilerSync(input_api, output_api))
    results.extend(_CheckDartApiWinCSync(input_api, output_api))
    return results


def CheckChangeOnCommit(input_api, output_api):
    return _CommonChecks(input_api, output_api)


def CheckChangeOnUpload(input_api, output_api):
    return _CommonChecks(input_api, output_api)
