"""Tests for git_utils."""

from __future__ import absolute_import
import os
import sys
import unittest

# Allow imports from cq/scripts folder
sys.path.insert(
    0,
    os.path.realpath(os.path.join(os.path.dirname(__file__), os.pardir)))
from helpers import git_utils
from helpers import repo_utils


# A mock executor that keeps simple git state.
class MockExecutor(object):

  def __init__(self):
    self.current_branch = 'HEAD'
    self.remote = ''
    self.remote_branch = ''
    self._handlers = []

  def add_handler(self, handler):
    self._handlers.append(handler)

  def exec_subprocess(self, command, cwd=None, check_output=False):

    for handler in self._handlers:
      result = handler(command, cwd)
      if result:
        if check_output:
          # check_output option only cares about stdout
          return result[1]
        return result

    if command[:2] == ['git', 'rev-parse']:
      return (0, self.current_branch, '')
    elif command[:2] == ['git', 'checkout']:
      self.current_branch = command[command.index('-B') + 1]
      self.remote, self.remote_branch = command[-1].split('/')

    return (0, '', '')


class GitUtilsTest(unittest.TestCase):

  def testNoFilterFiles(self):
    """Tests with no filter."""
    filenames = [
        'something.py',
        'something_else.cc'
    ]
    filtered_files = git_utils.filtered_files(filenames)
    self.assertEquals(filenames, filtered_files)

  def testNoFilteredFiles(self):
    """Tests filtering files by extension."""
    filenames = [
        'something.py',
        'something_else.cc'
    ]
    filtered_files = git_utils.filtered_files(filenames,
                                              file_extensions=['.py', '.cc'])
    self.assertEquals(2, len(filtered_files))
    self.assertIn('something.py', filtered_files)
    self.assertIn('something_else.cc', filtered_files)

  def testFilteredFiles(self):
    """Tests filtering files by extension."""
    filenames = [
        'something.py',
        'something_else.cc'
    ]
    filtered_files = git_utils.filtered_files(filenames,
                                              file_extensions=['.py'])
    self.assertEquals(1, len(filtered_files))
    self.assertIn('something.py', filtered_files)

  def testFilteredFilesExclusion(self):
    """Tests filtering files by pattern."""
    filenames = [
        'something.py',
        'something_foo_pb2.py',
        'something_else.cc'
    ]
    filtered_files = git_utils.filtered_files(
        filenames,
        file_extensions=['.py'],
        file_exclusion_pattern=r'^.+_pb2.py$')
    self.assertEquals(1, len(filtered_files))
    self.assertIn('something.py', filtered_files)

  def testGetAllFiles(self):
    """Test getting all files affected by a group of patches."""
    patches = [
        {'project': 'chromium/src', 'patchset_number': 12345},
        {'project': 'chromium/src', 'patchset_number': 67890},
        {'project': 'chromecast/internal', 'patchset_number': 34567},
        {'project': 'test', 'patchset_number': 89012},
        {'project': 'project_with_no_path', 'patchset_number': 1}]

    path_lookup = repo_utils.ProjectLookupTable({
        'chromium/src': 'chromium/src',
        'chromecast/internal': 'cast/internal',
        'test': 'test'})

    def handle_git_revlist(cmd, cwd):
      if cmd == ['git', 'rev-list', '--count', 'HEAD']:
        return (0, '200', '')
      return None

    def handle_git_diff(cmd, cwd):
      if cmd[:2] != ['git', 'diff'] or '--name-only' not in cmd:
        return None
      if cwd == 'chromium/src':
        self.assertTrue('HEAD~2' in cmd)
        files = ['base/logging.h', 'media/base/config.cc', 'net/utils.h']
      elif cwd == 'cast/internal':
        self.assertTrue('HEAD~1' in cmd)
        files = ['receiver/client.h', 'base/logging.h']
      elif cwd == 'test':
        self.assertTrue('HEAD~1' in cmd)
        files = ['foo.h']
      else:
        return (0, '', '')
      return (0, '\n'.join(files), '')

    executor = MockExecutor()
    executor.add_handler(handle_git_revlist)
    executor.add_handler(handle_git_diff)
    all_files = git_utils.get_changed_files_in_all_patches(
        executor, patches, path_lookup)
    self.assertEqual(set([
        'chromium/src/base/logging.h',
        'chromium/src/media/base/config.cc',
        'chromium/src/net/utils.h',
        'chromium/src/chromecast/internal/receiver/client.h',
        'chromium/src/chromecast/internal/base/logging.h',
        'test/foo.h']), set(all_files))

  def testIsRevisionASha(self):
    """Tests cases for git_utils.is_sha."""
    self.assertTrue(
        git_utils.is_sha('2fe8f3b110d8b117698265e18e432f32837247bb'))
    self.assertFalse(git_utils.is_sha('master'))
    self.assertFalse(git_utils.is_sha('unfork_m52'))


if __name__ == '__main__':
  unittest.main()
