# Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
#
# Use of this source code is governed by a BSD-style license
# that can be found in the LICENSE file in the root of the source
# tree. An additional intellectual property rights grant can be found
# in the file PATENTS.  All contributing project authors may
# be found in the AUTHORS file in the root of the source tree.

# This file is inspired to [1].
# [1] - https://cs.chromium.org/chromium/src/PRESUBMIT_test_mocks.py

import os.path
import re


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.
  """

    def __init__(self):
        self.change = MockChange([], [])
        self.files = []
        self.presubmit_local_path = os.path.dirname(__file__)

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

    def AffectedFiles(self, file_filter=None, include_deletes=False):
        # pylint: disable=unused-argument
        return self.files

    @classmethod
    def FilterSourceFile(cls,
                         affected_file,
                         files_to_check=(),
                         files_to_skip=()):
        # pylint: disable=unused-argument
        return True

    def PresubmitLocalPath(self):
        return self.presubmit_local_path

    def ReadFile(self, affected_file, mode='rU'):
        filename = affected_file.AbsoluteLocalPath()
        for f in self.files:
            if f.LocalPath() == filename:
                with open(filename, mode) as f:
                    return f.read()
        # 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 outputing
  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 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, bugs_from_description, tags=None):
        self._changed_files = changed_files
        self._bugs_from_description = bugs_from_description
        self.tags = dict() if not tags else tags

    def BugsFromDescription(self):
        return self._bugs_from_description

    def __getattr__(self, attr):
        """Return tags directly as attributes on the object."""
        if not re.match(r"^[A-Z_]*$", attr):
            raise AttributeError(self, attr)
        return self.tags.get(attr)


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=None,
                 old_contents=None,
                 action='A'):
        if new_contents is None:
            new_contents = ["Data"]
        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
        self._old_contents = old_contents

    def Action(self):
        return self._action

    def ChangedContents(self):
        return self._changed_contents

    def NewContents(self):
        return self._new_contents

    def LocalPath(self):
        return self._local_path

    def AbsoluteLocalPath(self):
        return self._local_path

    def OldContents(self):
        return self._old_contents
