# Copyright 2016 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 or at
# https://developers.google.com/open-source/licenses/bsd

"""Unit tests for sorting.py functions."""
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import

import unittest
# For convenient debugging
import logging

try:
  from mox3 import mox
except ImportError:
  import mox

from framework import sorting
from framework import framework_views
from proto import tracker_pb2
from testing import fake
from testing import testing_helpers
from tracker import tracker_bizobj


def MakeDescending(accessor):
  return sorting._MaybeMakeDescending(accessor, True)


class DescendingValueTest(unittest.TestCase):

  def testMinString(self):
    """When sorting desc, a min string will sort last instead of first."""
    actual = sorting.DescendingValue.MakeDescendingValue(sorting.MIN_STRING)
    self.assertEqual(sorting.MAX_STRING, actual)

  def testMaxString(self):
    """When sorting desc, a max string will sort first instead of last."""
    actual = sorting.DescendingValue.MakeDescendingValue(sorting.MAX_STRING)
    self.assertEqual(sorting.MIN_STRING, actual)

  def testDescValues(self):
    """The point of DescendingValue is to reverse the sort order."""
    anti_a = sorting.DescendingValue.MakeDescendingValue('a')
    anti_b = sorting.DescendingValue.MakeDescendingValue('b')
    self.assertTrue(anti_a > anti_b)

  def testMaybeMakeDescending(self):
    """It returns an accessor that makes DescendingValue iff arg is True."""
    asc_accessor = sorting._MaybeMakeDescending(lambda issue: 'a', False)
    asc_value = asc_accessor('fake issue')
    self.assertTrue(asc_value is 'a')

    desc_accessor = sorting._MaybeMakeDescending(lambda issue: 'a', True)
    print(desc_accessor)
    desc_value = desc_accessor('fake issue')
    self.assertTrue(isinstance(desc_value, sorting.DescendingValue))


class SortingTest(unittest.TestCase):

  def setUp(self):
    self.mox = mox.Mox()
    self.default_cols = 'a b c'
    self.builtin_cols = 'a b x y z'
    self.config = tracker_bizobj.MakeDefaultProjectIssueConfig(789)
    self.config.component_defs.append(tracker_bizobj.MakeComponentDef(
        11, 789, 'Database', 'doc', False, [], [], 0, 0))
    self.config.component_defs.append(tracker_bizobj.MakeComponentDef(
        22, 789, 'User Interface', 'doc', True, [], [], 0, 0))
    self.config.component_defs.append(tracker_bizobj.MakeComponentDef(
        33, 789, 'Installer', 'doc', False, [], [], 0, 0))

  def tearDown(self):
    self.mox.UnsetStubs()
    self.mox.ResetAll()

  def testMakeSingleSortKeyAccessor_Status(self):
    """Sorting by status should create an accessor for that column."""
    self.mox.StubOutWithMock(sorting, '_IndexOrLexical')
    status_names = [wks.status for wks in self.config.well_known_statuses]
    sorting._IndexOrLexical(status_names, 'status accessor')
    self.mox.ReplayAll()

    sorting._MakeSingleSortKeyAccessor(
      'status', self.config, {'status': 'status accessor'}, [], {}, [])
    self.mox.VerifyAll()

  def testMakeSingleSortKeyAccessor_Component(self):
    """Sorting by component should create an accessor for that column."""
    self.mox.StubOutWithMock(sorting, '_IndexListAccessor')
    component_ids = [11, 33, 22]
    sorting._IndexListAccessor(component_ids, 'component accessor')
    self.mox.ReplayAll()

    sorting._MakeSingleSortKeyAccessor(
      'component', self.config, {'component': 'component accessor'}, [], {}, [])
    self.mox.VerifyAll()

  def testMakeSingleSortKeyAccessor_OtherBuiltInColunms(self):
    """Sorting a built-in column should create an accessor for that column."""
    accessor = sorting._MakeSingleSortKeyAccessor(
      'buildincol', self.config, {'buildincol': 'accessor'}, [], {}, [])
    self.assertEqual('accessor', accessor)

  def testMakeSingleSortKeyAccessor_WithPostProcessor(self):
    """Sorting a built-in user column should create a user accessor."""
    self.mox.StubOutWithMock(sorting, '_MakeAccessorWithPostProcessor')
    users_by_id = {111: 'fake user'}
    sorting._MakeAccessorWithPostProcessor(
        users_by_id, 'mock owner accessor', 'mock postprocessor')
    self.mox.ReplayAll()

    sorting._MakeSingleSortKeyAccessor(
      'owner', self.config, {'owner': 'mock owner accessor'},
      {'owner': 'mock postprocessor'}, users_by_id, [])
    self.mox.VerifyAll()

  def testIndexOrLexical(self):
    well_known_values = ['x-a', 'x-b', 'x-c', 'x-d']
    art = 'this is a fake artifact'

    # Case 1: accessor generates no values.
    base_accessor = lambda art: None
    accessor = sorting._IndexOrLexical(well_known_values, base_accessor)
    self.assertEqual(sorting.MAX_STRING, accessor(art))
    neg_accessor = MakeDescending(accessor)
    self.assertEqual(sorting.DescendingValue(sorting.MAX_STRING),
                     neg_accessor(art))

    # Case 2: accessor generates a value, but it is an empty value.
    base_accessor = lambda art: ''
    accessor = sorting._IndexOrLexical(well_known_values, base_accessor)
    self.assertEqual(sorting.MAX_STRING, accessor(art))
    neg_accessor = MakeDescending(accessor)
    self.assertEqual(sorting.DescendingValue(sorting.MAX_STRING),
                     neg_accessor(art))

    # Case 3: A single well-known value
    base_accessor = lambda art: 'x-c'
    accessor = sorting._IndexOrLexical(well_known_values, base_accessor)
    self.assertEqual(2, accessor(art))
    neg_accessor = MakeDescending(accessor)
    self.assertEqual(-2, neg_accessor(art))

    # Case 4: A single odd-ball value
    base_accessor = lambda art: 'x-zzz'
    accessor = sorting._IndexOrLexical(well_known_values, base_accessor)
    self.assertEqual('x-zzz', accessor(art))
    neg_accessor = MakeDescending(accessor)
    self.assertEqual(
        sorting.DescendingValue('x-zzz'), neg_accessor(art))

  def testIndexListAccessor_SomeWellKnownValues(self):
    """Values sort according to their position in the well-known list."""
    well_known_values = [11, 33, 22]  # These represent component IDs.
    art = fake.MakeTestIssue(789, 1, 'sum 1', 'New', 111)
    base_accessor = lambda issue: issue.component_ids
    accessor = sorting._IndexListAccessor(well_known_values, base_accessor)

    # Case 1: accessor generates no values.
    self.assertEqual(sorting.MAX_STRING, accessor(art))
    neg_accessor = MakeDescending(accessor)
    self.assertEqual(sorting.MAX_STRING, neg_accessor(art))

    # Case 2: A single well-known value
    art.component_ids = [33]
    self.assertEqual([1], accessor(art))
    neg_accessor = MakeDescending(accessor)
    self.assertEqual([-1], neg_accessor(art))

    # Case 3: Multiple well-known and odd-ball values
    art.component_ids = [33, 11, 99]
    self.assertEqual([0, 1, sorting.MAX_STRING], accessor(art))
    neg_accessor = MakeDescending(accessor)
    self.assertEqual([sorting.MAX_STRING, -1, 0],
                     neg_accessor(art))

  def testIndexListAccessor_NoWellKnownValues(self):
    """When there are no well-known values, all values sort last."""
    well_known_values = []  # Nothing pre-defined, so everything is oddball
    art = fake.MakeTestIssue(789, 1, 'sum 1', 'New', 111)
    base_accessor = lambda issue: issue.component_ids
    accessor = sorting._IndexListAccessor(well_known_values, base_accessor)

    # Case 1: accessor generates no values.
    self.assertEqual(sorting.MAX_STRING, accessor(art))
    neg_accessor = MakeDescending(accessor)
    self.assertEqual(sorting.MAX_STRING, neg_accessor(art))

    # Case 2: A single oddball value
    art.component_ids = [33]
    self.assertEqual([sorting.MAX_STRING], accessor(art))
    neg_accessor = MakeDescending(accessor)
    self.assertEqual([sorting.MAX_STRING], neg_accessor(art))

    # Case 3: Multiple odd-ball values
    art.component_ids = [33, 11, 99]
    self.assertEqual(
      [sorting.MAX_STRING, sorting.MAX_STRING, sorting.MAX_STRING],
      accessor(art))
    neg_accessor = MakeDescending(accessor)
    self.assertEqual(
      [sorting.MAX_STRING, sorting.MAX_STRING, sorting.MAX_STRING],
      neg_accessor(art))

  def testIndexOrLexicalList(self):
    well_known_values = ['Pri-High', 'Pri-Med', 'Pri-Low']
    art = fake.MakeTestIssue(789, 1, 'sum 1', 'New', 111, merged_into=200001)

    # Case 1: accessor generates no values.
    accessor = sorting._IndexOrLexicalList(well_known_values, [], 'pri', {})
    self.assertEqual(sorting.MAX_STRING, accessor(art))
    neg_accessor = MakeDescending(accessor)
    self.assertEqual(sorting.MAX_STRING, neg_accessor(art))

    # Case 2: A single well-known value
    art.labels = ['Pri-Med']
    accessor = sorting._IndexOrLexicalList(well_known_values, [], 'pri', {})
    self.assertEqual([1], accessor(art))
    neg_accessor = MakeDescending(accessor)
    self.assertEqual([-1], neg_accessor(art))

    # Case 3: Multiple well-known and odd-ball values
    art.labels = ['Pri-zzz', 'Pri-Med', 'yyy', 'Pri-High']
    accessor = sorting._IndexOrLexicalList(well_known_values, [], 'pri', {})
    self.assertEqual([0, 1, 'zzz'], accessor(art))
    neg_accessor = MakeDescending(accessor)
    self.assertEqual([sorting.DescendingValue('zzz'), -1, 0],
                     neg_accessor(art))

    # Case 4: Multi-part prefix.
    well_known_values.extend(['X-Y-Header', 'X-Y-Footer'])
    art.labels = ['X-Y-Footer', 'X-Y-Zone', 'X-Y-Header', 'X-Y-Area']
    accessor = sorting._IndexOrLexicalList(well_known_values, [], 'x-y', {})
    self.assertEqual([3, 4, 'area', 'zone'], accessor(art))
    neg_accessor = MakeDescending(accessor)
    self.assertEqual([sorting.DescendingValue('zone'),
                      sorting.DescendingValue('area'), -4, -3],
                     neg_accessor(art))

  def testIndexOrLexicalList_CustomFields(self):
    art = fake.MakeTestIssue(789, 1, 'sum 2', 'New', 111)
    art.labels = ['samename-value1']
    art.field_values = [tracker_bizobj.MakeFieldValue(
        3, 6078, None, None, None, None, False)]

    all_field_defs = [
        tracker_bizobj.MakeFieldDef(
            3, 789, 'samename', tracker_pb2.FieldTypes.INT_TYPE,
            None, None, False, False, False, None, None, None, False, None,
            None, None, None, 'cow spots', False),
        tracker_bizobj.MakeFieldDef(
            4, 788, 'samename', tracker_pb2.FieldTypes.APPROVAL_TYPE,
            None, None, False, False, False, None, None, None, False, None,
            None, None, None, 'cow spots', False),
        tracker_bizobj.MakeFieldDef(
            4, 788, 'notsamename', tracker_pb2.FieldTypes.APPROVAL_TYPE,
            None, None, False, False, False, None, None, None, False, None,
            None, None, None, 'should get filtered out', False)
    ]

    accessor = sorting._IndexOrLexicalList([], all_field_defs, 'samename', {})
    self.assertEqual([6078, 'value1'], accessor(art))
    neg_accessor = MakeDescending(accessor)
    self.assertEqual(
        [sorting.DescendingValue('value1'), -6078], neg_accessor(art))

  def testIndexOrLexicalList_PhaseCustomFields(self):
    art = fake.MakeTestIssue(789, 1, 'sum 2', 'New', 111)
    art.labels = ['summer.goats-value1']
    art.field_values = [
        tracker_bizobj.MakeFieldValue(
            3, 33, None, None, None, None, False, phase_id=77),
        tracker_bizobj.MakeFieldValue(
            3, 34, None, None, None, None, False, phase_id=77),
        tracker_bizobj.MakeFieldValue(
            3, 1000, None, None, None, None, False, phase_id=78)]
    art.phases = [tracker_pb2.Phase(phase_id=77, name='summer'),
                  tracker_pb2.Phase(phase_id=78, name='winter')]

    all_field_defs = [
        tracker_bizobj.MakeFieldDef(
            3, 789, 'goats', tracker_pb2.FieldTypes.INT_TYPE,
            None, None, False, False, True, None, None, None, False, None,
            None, None, None, 'goats love mineral', False, is_phase_field=True),
        tracker_bizobj.MakeFieldDef(
            4, 788, 'boo', tracker_pb2.FieldTypes.APPROVAL_TYPE,
            None, None, False, False, False, None, None, None, False, None,
            None, None, None, 'ahh', False),
        ]

    accessor = sorting._IndexOrLexicalList(
        [], all_field_defs, 'summer.goats', {})
    self.assertEqual([33, 34, 'value1'], accessor(art))
    neg_accessor = MakeDescending(accessor)
    self.assertEqual(
        [sorting.DescendingValue('value1'), -34, -33], neg_accessor(art))

  def testIndexOrLexicalList_ApprovalStatus(self):
    art = fake.MakeTestIssue(789, 1, 'sum 2', 'New', 111)
    art.labels = ['samename-value1']
    art.approval_values = [tracker_pb2.ApprovalValue(approval_id=4)]

    all_field_defs = [
        tracker_bizobj.MakeFieldDef(
            3, 789, 'samename', tracker_pb2.FieldTypes.INT_TYPE,
            None, None, False, False, False, None, None, None, False, None,
            None, None, None, 'cow spots', False),
        tracker_bizobj.MakeFieldDef(
            4, 788, 'samename', tracker_pb2.FieldTypes.APPROVAL_TYPE,
            None, None, False, False, False, None, None, None, False, None,
            None, None, None, 'cow spots', False)
    ]

    accessor = sorting._IndexOrLexicalList([], all_field_defs, 'samename', {})
    self.assertEqual([0, 'value1'], accessor(art))
    neg_accessor = MakeDescending(accessor)
    self.assertEqual([sorting.DescendingValue('value1'),
                      sorting.DescendingValue(0)],
                     neg_accessor(art))

  def testIndexOrLexicalList_ApprovalApprover(self):
    art = art = fake.MakeTestIssue(789, 1, 'sum 2', 'New', 111)
    art.labels = ['samename-approver-value1']
    art.approval_values = [
        tracker_pb2.ApprovalValue(approval_id=4, approver_ids=[333])]

    all_field_defs = [
        tracker_bizobj.MakeFieldDef(
            4, 788, 'samename', tracker_pb2.FieldTypes.APPROVAL_TYPE,
            None, None, False, False, False, None, None, None, False, None,
            None, None, None, 'cow spots', False)
    ]
    users_by_id = {333: framework_views.StuffUserView(333, 'a@test.com', True)}

    accessor = sorting._IndexOrLexicalList(
        [], all_field_defs, 'samename-approver', users_by_id)
    self.assertEqual(['a@test.com', 'value1'], accessor(art))
    neg_accessor = MakeDescending(accessor)
    self.assertEqual([sorting.DescendingValue('value1'),
                      sorting.DescendingValue('a@test.com')],
                     neg_accessor(art))

  def testComputeSortDirectives(self):
    config = tracker_pb2.ProjectIssueConfig()
    self.assertEqual(
        ['project', 'id'], sorting.ComputeSortDirectives(config, '', ''))

    self.assertEqual(
        ['a', 'b', 'c', 'project', 'id'],
        sorting.ComputeSortDirectives(config, '', 'a b C'))

    config.default_sort_spec = 'id -reporter Owner'
    self.assertEqual(
        ['id', '-reporter', 'owner', 'project'],
        sorting.ComputeSortDirectives(config, '', ''))

    self.assertEqual(
        ['x', '-b', 'a', 'c', '-owner', 'id', '-reporter', 'project'],
        sorting.ComputeSortDirectives(config, 'x -b', 'A -b c -owner'))
