# Copyright 2023 Google Inc.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# This is a copy of PRESUBMIT_test_mocks.py from the Chromium project.

from collections import defaultdict
import fnmatch
import json
import os
import re
import subprocess
import sys


def _ReportErrorFileAndLine(filename, line_num, dummy_line):
    """Default error formatter for _FindNewViolationsOfRule."""
    return '%s:%s' % (filename, line_num)


class MockCannedChecks(object):
    def _FindNewViolationsOfRule(self, callable_rule, input_api,
                                 source_file_filter=None,
                                 error_formatter=_ReportErrorFileAndLine):
        """Find all newly introduced violations of a per-line rule (a callable).

        Arguments:
          callable_rule: a callable taking a file extension and line of input and
            returning True if the rule is satisfied and False if there was a
            problem.
          input_api: object to enumerate the affected files.
          source_file_filter: a filter to be passed to the input api.
          error_formatter: a callable taking (filename, line_number, line) and
            returning a formatted error string.

        Returns:
          A list of the newly-introduced violations reported by the rule.
        """
        errors = []
        for f in input_api.AffectedFiles(include_deletes=False,
                                         file_filter=source_file_filter):
            # For speed, we do two passes, checking first the full file.  Shelling out
            # to the SCM to determine the changed region can be quite expensive on
            # Win32.  Assuming that most files will be kept problem-free, we can
            # skip the SCM operations most of the time.
            extension = str(f.LocalPath()).rsplit('.', 1)[-1]
            if all(callable_rule(extension, line) for line in f.NewContents()):
                # No violation found in full text: can skip considering diff.
                continue

            for line_num, line in f.ChangedContents():
                if not callable_rule(extension, line):
                    errors.append(error_formatter(
                        f.LocalPath(), line_num, line))

        return errors


class MockInputApi(object):
    """Mock class for the InputApi class.

    This class can be used for unittests for presubmit by initializing the files
    attribute as the list of changed files.
    """

    DEFAULT_FILES_TO_SKIP = ()

    def __init__(self):
        self.canned_checks = MockCannedChecks()
        self.fnmatch = fnmatch
        self.json = json
        self.re = re
        self.os_path = os.path
        self.platform = sys.platform
        self.python_executable = sys.executable
        self.python3_executable = sys.executable
        self.platform = sys.platform
        self.subprocess = subprocess
        self.sys = sys
        self.files = []
        self.is_committing = False
        self.change = MockChange([])
        self.presubmit_local_path = os.path.dirname(__file__)
        self.is_windows = sys.platform == 'win32'
        self.no_diffs = False
        # Although this makes assumptions about command line arguments used by test
        # scripts that create mocks, it is a convenient way to set up the verbosity
        # via the input api.
        self.verbose = '--verbose' in sys.argv

    def CreateMockFileInPath(self, f_list):
        self.os_path.exists = lambda x: x in f_list

    def AffectedFiles(self, file_filter=None, include_deletes=True):
        for file in self.files:
            if file_filter and not file_filter(file):
                continue
            if not include_deletes and file.Action() == 'D':
                continue
            yield file

    def RightHandSideLines(self, source_file_filter=None):
        affected_files = self.AffectedSourceFiles(source_file_filter)
        for af in affected_files:
            lines = af.ChangedContents()
            for line in lines:
                yield (af, line[0], line[1])

    def AffectedSourceFiles(self, file_filter=None):
        return self.AffectedFiles(file_filter=file_filter)

    def FilterSourceFile(self, file,
                         files_to_check=(), files_to_skip=()):
        local_path = file.LocalPath()
        found_in_files_to_check = not files_to_check
        if files_to_check:
            if type(files_to_check) is str:
                raise TypeError(
                    'files_to_check should be an iterable of strings')
            for pattern in files_to_check:
                compiled_pattern = re.compile(pattern)
                if compiled_pattern.match(local_path):
                    found_in_files_to_check = True
                    break
        if files_to_skip:
            if type(files_to_skip) is str:
                raise TypeError(
                    'files_to_skip should be an iterable of strings')
            for pattern in files_to_skip:
                compiled_pattern = re.compile(pattern)
                if compiled_pattern.match(local_path):
                    return False
        return found_in_files_to_check

    def LocalPaths(self):
        return [file.LocalPath() for file in self.files]

    def PresubmitLocalPath(self):
        return self.presubmit_local_path

    def ReadFile(self, filename, mode='r'):
        if hasattr(filename, 'AbsoluteLocalPath'):
            filename = filename.AbsoluteLocalPath()
        for file_ in self.files:
            if file_.LocalPath() == filename:
                return '\n'.join(file_.NewContents())
        # Otherwise, file is not in our mock API.
        raise IOError("No such file or directory: '%s'" % filename)


class MockOutputApi(object):
    """Mock class for the OutputApi class.

    An instance of this class can be passed to presubmit unittests for outputting
    various types of results.
    """

    class PresubmitResult(object):
        def __init__(self, message, items=None, long_text=''):
            self.message = message
            self.items = items
            self.long_text = long_text

        def __repr__(self):
            return self.message

    class PresubmitError(PresubmitResult):
        def __init__(self, message, items=None, long_text=''):
            MockOutputApi.PresubmitResult.__init__(
                self, message, items, long_text)
            self.type = 'error'

    class PresubmitPromptWarning(PresubmitResult):
        def __init__(self, message, items=None, long_text=''):
            MockOutputApi.PresubmitResult.__init__(
                self, message, items, long_text)
            self.type = 'warning'

    class PresubmitNotifyResult(PresubmitResult):
        def __init__(self, message, items=None, long_text=''):
            MockOutputApi.PresubmitResult.__init__(
                self, message, items, long_text)
            self.type = 'notify'

    class PresubmitPromptOrNotify(PresubmitResult):
        def __init__(self, message, items=None, long_text=''):
            MockOutputApi.PresubmitResult.__init__(
                self, message, items, long_text)
            self.type = 'promptOrNotify'

    def __init__(self):
        self.more_cc = []

    def AppendCC(self, more_cc):
        self.more_cc.append(more_cc)


class MockFile(object):
    """Mock class for the File class.

    This class can be used to form the mock list of changed files in
    MockInputApi for presubmit unittests.
    """

    def __init__(self, local_path, new_contents, old_contents=None, action='A',
                 scm_diff=None):
        self._local_path = local_path
        self._new_contents = new_contents
        self._changed_contents = [(i + 1, l)
                                  for i, l in enumerate(new_contents)]
        self._action = action
        if scm_diff:
            self._scm_diff = scm_diff
        else:
            self._scm_diff = (
                "--- /dev/null\n+++ %s\n@@ -0,0 +1,%d @@\n" %
                (local_path, len(new_contents)))
            for l in new_contents:
                self._scm_diff += "+%s\n" % l
        self._old_contents = old_contents

    def Action(self):
        return self._action

    def ChangedContents(self):
        return self._changed_contents

    def NewContents(self, flush_cache=False):
        return self._new_contents

    def LocalPath(self):
        return self._local_path

    def AbsoluteLocalPath(self):
        return self._local_path

    def GenerateScmDiff(self):
        return self._scm_diff

    def OldContents(self):
        return self._old_contents

    def rfind(self, p):
        """os.path.basename is called on MockFile so we need an rfind method."""
        return self._local_path.rfind(p)

    def __getitem__(self, i):
        """os.path.basename is called on MockFile so we need a get method."""
        return self._local_path[i]

    def __len__(self):
        """os.path.basename is called on MockFile so we need a len method."""
        return len(self._local_path)

    def replace(self, altsep, sep):
        """os.path.basename is called on MockFile so we need a replace method."""
        return self._local_path.replace(altsep, sep)


class MockAffectedFile(MockFile):
    def AbsoluteLocalPath(self):
        return self._local_path


class MockChange(object):
    """Mock class for Change class.

    This class can be used in presubmit unittests to mock the query of the
    current change.
    """

    def __init__(self, changed_files):
        self._changed_files = changed_files
        self.author_email = None
        self.footers = defaultdict(list)

    def LocalPaths(self):
        return self._changed_files

    def AffectedFiles(self, include_dirs=False, include_deletes=True,
                      file_filter=None):
        return self._changed_files

    def GitFootersFromDescription(self):
        return self.footers
