#!/usr/bin/env vpython3
# Copyright 2013 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Unit tests for owners_finder.py."""

import os
import sys
import unittest


sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from testing_support import filesystem_mock

import owners_finder
import owners


ben = 'ben@example.com'
brett = 'brett@example.com'
darin = 'darin@example.com'
jochen = 'jochen@example.com'
john = 'john@example.com'
ken = 'ken@example.com'
peter = 'peter@example.com'
tom = 'tom@example.com'
nonowner = 'nonowner@example.com'


def owners_file(*email_addresses, **kwargs):
  s = ''
  if kwargs.get('comment'):
    s += '# %s\n' % kwargs.get('comment')
  if kwargs.get('noparent'):
    s += 'set noparent\n'
  return s + '\n'.join(email_addresses) + '\n'


def test_repo():
  return filesystem_mock.MockFileSystem(files={
    '/DEPS': '',
    '/OWNERS': owners_file(ken, peter, tom,
                           comment='OWNERS_STATUS = build/OWNERS.status'),
    '/build/OWNERS.status': '%s: bar' % jochen,
    '/base/vlog.h': '',
    '/chrome/OWNERS': owners_file(ben, brett),
    '/chrome/browser/OWNERS': owners_file(brett),
    '/chrome/browser/defaults.h': '',
    '/chrome/gpu/OWNERS': owners_file(ken),
    '/chrome/gpu/gpu_channel.h': '',
    '/chrome/renderer/OWNERS': owners_file(peter),
    '/chrome/renderer/gpu/gpu_channel_host.h': '',
    '/chrome/renderer/safe_browsing/scorer.h': '',
    '/content/OWNERS': owners_file(john, darin, comment='foo', noparent=True),
    '/content/content.gyp': '',
    '/content/bar/foo.cc': '',
    '/content/baz/OWNERS': owners_file(brett),
    '/content/baz/froboz.h': '',
    '/content/baz/ugly.cc': '',
    '/content/baz/ugly.h': '',
    '/content/common/OWNERS': owners_file(jochen),
    '/content/common/common.cc': '',
    '/content/foo/OWNERS': owners_file(jochen, comment='foo'),
    '/content/foo/foo.cc': '',
    '/content/views/OWNERS': owners_file(ben, john, owners.EVERYONE,
                                         noparent=True),
    '/content/views/pie.h': '',
  })


class OutputInterceptedOwnersFinder(owners_finder.OwnersFinder):
  def __init__(self, files, local_root, author, reviewers,
               fopen, os_path, disable_color=False):
    super(OutputInterceptedOwnersFinder, self).__init__(
      files, local_root, author, reviewers, fopen, os_path,
      disable_color=disable_color)
    self.output = []
    self.indentation_stack = []

  def resetText(self):
    self.output = []
    self.indentation_stack = []

  def indent(self):
    self.indentation_stack.append(self.output)
    self.output = []

  def unindent(self):
    block = self.output
    self.output = self.indentation_stack.pop()
    self.output.append(block)

  def writeln(self, text=''):
    self.output.append(text)


class _BaseTestCase(unittest.TestCase):
  default_files = [
    'base/vlog.h',
    'chrome/browser/defaults.h',
    'chrome/gpu/gpu_channel.h',
    'chrome/renderer/gpu/gpu_channel_host.h',
    'chrome/renderer/safe_browsing/scorer.h',
    'content/content.gyp',
    'content/bar/foo.cc',
    'content/baz/ugly.cc',
    'content/baz/ugly.h',
    'content/views/pie.h'
  ]

  def setUp(self):
    self.repo = test_repo()
    self.root = '/'
    self.fopen = self.repo.open_for_reading

  def ownersFinder(self, files, author=nonowner, reviewers=None):
    reviewers = reviewers or []
    finder = OutputInterceptedOwnersFinder(files,
                                           self.root,
                                           author,
                                           reviewers,
                                           fopen=self.fopen,
                                           os_path=self.repo,
                                           disable_color=True)
    return finder

  def defaultFinder(self):
    return self.ownersFinder(self.default_files)


class OwnersFinderTests(_BaseTestCase):
  def test_constructor(self):
    self.assertNotEqual(self.defaultFinder(), None)

  def test_skip_files_owned_by_reviewers(self):
    files = [
        'chrome/browser/defaults.h',  # owned by brett
        'content/bar/foo.cc',         # not owned by brett
    ]
    finder = self.ownersFinder(files, reviewers=[brett])
    self.assertEqual(finder.unreviewed_files, {'content/bar/foo.cc'})

  def test_skip_files_owned_by_author(self):
    files = [
        'chrome/browser/defaults.h',  # owned by brett
        'content/bar/foo.cc',         # not owned by brett
    ]
    finder = self.ownersFinder(files, author=brett)
    self.assertEqual(finder.unreviewed_files, {'content/bar/foo.cc'})

  def test_native_path_sep(self):
    # Create a path with backslashes on Windows to make sure these are handled.
    # This test is a harmless duplicate on other platforms.
    native_slashes_path = 'chrome/browser/defaults.h'.replace('/', os.sep)
    files = [
        native_slashes_path,          # owned by brett
        'content/bar/foo.cc',         # not owned by brett
    ]
    finder = self.ownersFinder(files, reviewers=[brett])
    self.assertEqual(finder.unreviewed_files, {'content/bar/foo.cc'})

  def test_reset(self):
    finder = self.defaultFinder()
    for _ in range(2):
      expected = [brett, darin, john, peter, ken, ben, tom]
      # darin and john have equal cost, the others have distinct costs.
      # If the owners_queue has those two swapped then swap them in expected.
      if finder.owners_queue[1] != expected[1]:
        expected[1], expected[2] = expected[2], expected[1]
      self.assertEqual(finder.owners_queue, expected)
      self.assertEqual(finder.unreviewed_files, {
          'base/vlog.h',
          'chrome/browser/defaults.h',
          'chrome/gpu/gpu_channel.h',
          'chrome/renderer/gpu/gpu_channel_host.h',
          'chrome/renderer/safe_browsing/scorer.h',
          'content/content.gyp',
          'content/bar/foo.cc',
          'content/baz/ugly.cc',
          'content/baz/ugly.h'
      })
      self.assertEqual(finder.selected_owners, set())
      self.assertEqual(finder.deselected_owners, set())
      self.assertEqual(finder.reviewed_by, {})
      self.assertEqual(finder.output, [])

      finder.select_owner(john)
      finder.reset()
      finder.resetText()

  def test_select(self):
    finder = self.defaultFinder()
    finder.select_owner(john)
    self.assertEqual(finder.owners_queue, [brett, peter, ken, ben, tom])
    self.assertEqual(finder.selected_owners, {john})
    self.assertEqual(finder.deselected_owners, {darin})
    self.assertEqual(finder.reviewed_by, {'content/bar/foo.cc': john,
                                          'content/baz/ugly.cc': john,
                                          'content/baz/ugly.h': john,
                                          'content/content.gyp': john})
    self.assertEqual(finder.output,
                     ['Selected: ' + john, 'Deselected: ' + darin])

    finder = self.defaultFinder()
    finder.select_owner(darin)
    self.assertEqual(finder.owners_queue, [brett, peter, ken, ben, tom])
    self.assertEqual(finder.selected_owners, {darin})
    self.assertEqual(finder.deselected_owners, {john})
    self.assertEqual(finder.reviewed_by, {'content/bar/foo.cc': darin,
                                          'content/baz/ugly.cc': darin,
                                          'content/baz/ugly.h': darin,
                                          'content/content.gyp': darin})
    self.assertEqual(finder.output,
                     ['Selected: ' + darin, 'Deselected: ' + john])

    finder = self.defaultFinder()
    finder.select_owner(brett)
    expected = [darin, john, peter, ken, tom]
    # darin and john have equal cost, the others have distinct costs.
    # If the owners_queue has those two swapped then swap them in expected.
    if finder.owners_queue[0] == john:
      expected[0], expected[1] = expected[1], expected[0]

    self.assertEqual(finder.owners_queue, expected)
    self.assertEqual(finder.selected_owners, {brett})
    self.assertEqual(finder.deselected_owners, {ben})
    self.assertEqual(finder.reviewed_by,
                     {'chrome/browser/defaults.h': brett,
                      'chrome/gpu/gpu_channel.h': brett,
                      'chrome/renderer/gpu/gpu_channel_host.h': brett,
                      'chrome/renderer/safe_browsing/scorer.h': brett,
                      'content/baz/ugly.cc': brett,
                      'content/baz/ugly.h': brett})
    self.assertEqual(finder.output,
                     ['Selected: ' + brett, 'Deselected: ' + ben])

  def test_deselect(self):
    finder = self.defaultFinder()
    finder.deselect_owner(john)
    self.assertEqual(finder.owners_queue, [brett, peter, ken, ben, tom])
    self.assertEqual(finder.selected_owners, {darin})
    self.assertEqual(finder.deselected_owners, {john})
    self.assertEqual(finder.reviewed_by, {'content/bar/foo.cc': darin,
                                          'content/baz/ugly.cc': darin,
                                          'content/baz/ugly.h': darin,
                                          'content/content.gyp': darin})
    self.assertEqual(finder.output,
                     ['Deselected: ' + john, 'Selected: ' + darin])

  def test_print_file_info(self):
    finder = self.defaultFinder()
    finder.print_file_info('chrome/browser/defaults.h')
    self.assertEqual(finder.output, ['chrome/browser/defaults.h [5]'])
    finder.resetText()

    finder.print_file_info('chrome/renderer/gpu/gpu_channel_host.h')
    self.assertEqual(finder.output,
                     ['chrome/renderer/gpu/gpu_channel_host.h [5]'])

  def test_print_file_info_detailed(self):
    finder = self.defaultFinder()
    finder.print_file_info_detailed('chrome/browser/defaults.h')
    self.assertEqual(finder.output,
                     ['chrome/browser/defaults.h',
                       [ben, brett, ken, peter, tom]])
    finder.resetText()

    finder.print_file_info_detailed('chrome/renderer/gpu/gpu_channel_host.h')
    self.assertEqual(finder.output,
                     ['chrome/renderer/gpu/gpu_channel_host.h',
                       [ben, brett, ken, peter, tom]])

  def test_print_comments(self):
    finder = self.defaultFinder()
    finder.print_comments(darin)
    self.assertEqual(finder.output,
                     [darin + ' is commented as:', ['foo (at content)']])

  def test_print_global_comments(self):
    finder = self.ownersFinder(['content/common/common.cc'])
    finder.print_comments(jochen)
    self.assertEqual(finder.output,
                     [jochen + ' is commented as:', ['bar (global status)']])

    finder = self.ownersFinder(['content/foo/foo.cc'])
    finder.print_comments(jochen)
    self.assertEqual(finder.output,
                     [jochen + ' is commented as:', ['bar (global status)',
                                                     'foo (at content/foo)']])

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