from ...revision import Revision
from ...tests import TestCase, TestCaseWithTransport
from .cmds import collapse_by_person, get_revisions_and_committers


class TestGetRevisionsAndCommitters(TestCaseWithTransport):

    def test_simple(self):
        wt = self.make_branch_and_tree('.')
        wt.commit(message='1', committer='Fero <fero@example.com>', rev_id=b'1')
        wt.commit(message='2', committer='Fero <fero@example.com>', rev_id=b'2')
        wt.commit(message='3', committer='Jano <jano@example.com>', rev_id=b'3')
        wt.commit(message='4', committer='Jano <jano@example.com>',
                  authors=['Vinco <vinco@example.com>'], rev_id=b'4')
        wt.commit(message='5', committer='Ferko <fero@example.com>', rev_id=b'5')
        revs, committers = get_revisions_and_committers(wt.branch.repository,
                                                        [b'1', b'2', b'3', b'4', b'5'])
        fero = ('Fero', 'fero@example.com')
        jano = ('Jano', 'jano@example.com')
        vinco = ('Vinco', 'vinco@example.com')
        ferok = ('Ferko', 'fero@example.com')
        self.assertEqual({fero: fero, jano: jano, vinco: vinco, ferok: fero},
                         committers)

    def test_empty_email(self):
        wt = self.make_branch_and_tree('.')
        wt.commit(message='1', committer='Fero', rev_id=b'1')
        wt.commit(message='2', committer='Fero', rev_id=b'2')
        wt.commit(message='3', committer='Jano', rev_id=b'3')
        revs, committers = get_revisions_and_committers(wt.branch.repository,
                                                        [b'1', b'2', b'3'])
        self.assertEqual({('Fero', ''): ('Fero', ''),
                          ('Jano', ''): ('Jano', ''),
                          }, committers)

    def test_different_case(self):
        wt = self.make_branch_and_tree('.')
        wt.commit(message='1', committer='Fero', rev_id=b'1')
        wt.commit(message='2', committer='Fero', rev_id=b'2')
        wt.commit(message='3', committer='FERO', rev_id=b'3')
        revs, committers = get_revisions_and_committers(wt.branch.repository,
                                                        [b'1', b'2', b'3'])
        self.assertEqual({('Fero', ''): ('Fero', ''),
                          ('FERO', ''): ('Fero', ''),
                          }, committers)
        self.assertEqual([b'1', b'2', b'3'], sorted(
            [r.revision_id for r in revs]))


class TestCollapseByPerson(TestCase):

    def test_no_conflicts(self):
        revisions = [
            Revision('1', {}, committer='Foo <foo@example.com>'),
            Revision('2', {}, committer='Bar <bar@example.com>'),
            Revision('3', {}, committer='Bar <bar@example.com>'),
        ]
        foo = ('Foo', 'foo@example.com')
        bar = ('Bar', 'bar@example.com')
        committers = {foo: foo, bar: bar}
        info = collapse_by_person(revisions, committers)
        self.assertEqual(2, info[0][0])
        self.assertEqual({'bar@example.com': 2}, info[0][2])
        self.assertEqual({'Bar': 2}, info[0][3])

    def test_different_email(self):
        revisions = [
            Revision('1', {}, committer='Foo <foo@example.com>'),
            Revision('2', {}, committer='Foo <bar@example.com>'),
            Revision('3', {}, committer='Foo <bar@example.com>'),
        ]
        foo = ('Foo', 'foo@example.com')
        bar = ('Foo', 'bar@example.com')
        committers = {foo: foo, bar: foo}
        info = collapse_by_person(revisions, committers)
        self.assertEqual(3, info[0][0])
        self.assertEqual(
            {'foo@example.com': 1, 'bar@example.com': 2}, info[0][2])
        self.assertEqual({'Foo': 3}, info[0][3])

    def test_different_name(self):
        revisions = [
            Revision('1', {}, committer='Foo <foo@example.com>'),
            Revision('2', {}, committer='Bar <foo@example.com>'),
            Revision('3', {}, committer='Bar <foo@example.com>'),
        ]
        foo = ('Foo', 'foo@example.com')
        bar = ('Bar', 'foo@example.com')
        committers = {foo: foo, bar: foo}
        info = collapse_by_person(revisions, committers)
        self.assertEqual(3, info[0][0])
        self.assertEqual({'foo@example.com': 3}, info[0][2])
        self.assertEqual({'Foo': 1, 'Bar': 2}, info[0][3])

    def test_different_name_case(self):
        revisions = [
            Revision('1', {}, committer='Foo <foo@example.com>'),
            Revision('2', {}, committer='Foo <foo@example.com>'),
            Revision('3', {}, committer='FOO <bar@example.com>'),
        ]
        foo = ('Foo', 'foo@example.com')
        FOO = ('FOO', 'bar@example.com')
        committers = {foo: foo, FOO: foo}
        info = collapse_by_person(revisions, committers)
        self.assertEqual(3, info[0][0])
        self.assertEqual(
            {'foo@example.com': 2, 'bar@example.com': 1}, info[0][2])
        self.assertEqual({'Foo': 2, 'FOO': 1}, info[0][3])
