# Copyright (C) 2005, 2006, 2007, 2008, 2009 Canonical Ltd
# Copyright (C) 2008, 2009 Guillermo Gonzalez
# -*- coding: utf-8 -*-
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA


"""Black-box tests for bzr log."""

import os

import bzrlib
from bzrlib import osutils
from bzrlib.tests.blackbox import ExternalBase
from bzrlib.tests import TestCaseInTempDir, TestCaseWithTransport
from bzrlib.xml_serializer import elementtree as elementtree
fromstring = elementtree.fromstring
elementtree_tostring = elementtree.tostring

class TestLog(ExternalBase):

    def _prepare(self, path='.', format=None):
        tree = self.make_branch_and_tree(path, format=format)
        self.build_tree(
            [path + '/hello.txt', path + '/goodbye.txt', path + '/meep.txt'])
        tree.add('hello.txt')
        tree.commit(message='message1')
        tree.add('goodbye.txt')
        tree.commit(message='message2')
        tree.add('meep.txt')
        tree.commit(message='message3')
        self.full_log_xml = fromstring(self.run_bzr(["xmllog", path])[0])
        return tree

    def test_log_null_end_revspec(self):
        self._prepare()
        for revno in self.full_log_xml.findall('log/revno'):
            self.assertTrue(revno.text in ['1', '2', '3'])
        for message in self.full_log_xml.findall('log/message'):
            self.assertTrue(message.text.strip() in
                            ['message1', 'message2', 'message3'])

        log_xml = fromstring(self.run_bzr("xmllog -r 1..")[0])
        for elem1, elem2 in zip(log_xml.getiterator(),
                                self.full_log_xml.getiterator()):
            self.assertEquals(elem1.tag, elem2.tag)
            self.assertEquals(elem1.text, elem2.text)
        #self.assertEqualDiff(log_xml, self.full_log_xml)

    def test_log_null_begin_revspec(self):
        self._prepare()
        log_xml = fromstring(self.run_bzr("xmllog -r ..3")[0])
        #self.assertEqualDiff(self.full_log, log)
        for elem1, elem2 in zip(log_xml.getiterator(),
                                self.full_log_xml.getiterator()):
            self.assertEquals(elem1.tag, elem2.tag)
            self.assertEquals(elem1.text, elem2.text)

    def test_log_null_both_revspecs(self):
        self._prepare()
        log_xml = fromstring(self.run_bzr("xmllog -r ..")[0])
        #self.assertEquals(self.full_log, log)
        #self.assertEqualDiff(self.full_log, log)
        for elem1, elem2 in zip(log_xml.getiterator(),
                                self.full_log_xml.getiterator()):
            self.assertEquals(elem1.tag, elem2.tag)
            self.assertEquals(elem1.text, elem2.text)

    def test_log_negative_begin_revspec_full_log(self):
        self._prepare()
        log_xml = fromstring(self.run_bzr("xmllog -r -3..")[0])
        #self.assertEqualDiff(self.full_log, log)
        for elem1, elem2 in zip(log_xml.getiterator(),
                                self.full_log_xml.getiterator()):
            self.assertEquals(elem1.tag, elem2.tag)
            self.assertEquals(elem1.text, elem2.text)

    def test_log_negative_both_revspec_full_log(self):
        self._prepare()
        log_xml = fromstring(self.run_bzr("xmllog -r -3..-1")[0])
        #self.assertEqualDiff(self.full_log, log)
        for elem1, elem2 in zip(log_xml.getiterator(),
                                self.full_log_xml.getiterator()):
            self.assertEquals(elem1.tag, elem2.tag)
            self.assertEquals(elem1.text, elem2.text)

    def test_log_negative_both_revspec_partial(self):
        self._prepare()
        log_xml = fromstring(self.run_bzr("xmllog -r -3..-2")[0])
        #self.assertTrue('revno: 1\n' in log)
        #self.assertTrue('revno: 2\n' in log)
        #self.assertTrue('revno: 3\n' not in log)
        for revno in log_xml.findall('log/revno'):
            self.assertTrue(revno.text in ['1', '2'])
            self.assertTrue(revno.text not in ['3'])

    def test_log_negative_begin_revspec(self):
        self._prepare()
        log_xml = fromstring(self.run_bzr("xmllog -r -2..")[0])
        for revno in log_xml.findall('log/revno'):
            self.assertTrue(revno.text in ['2', '3'])
            self.assertTrue(revno.text not in ['1'])
        #self.assertTrue('revno: 1\n' not in log)
        #self.assertTrue('revno: 2\n' in log)
        #self.assertTrue('revno: 3\n' in log)

    def test_log_postive_revspecs(self):
        self._prepare()
        log_xml = fromstring(self.run_bzr("xmllog -r 1..3")[0])
      
  #self.assertEqualDiff(self.full_log, log)
        for elem1, ele
m2 in zip(log_xml.getiterator(), \
                    self.full_log_xml.getiterator()):
            self.assertEquals(elem1.tag, elem2.tag)
            self.assertEquals(elem1.text, elem2.text)

    def test_log_reversed_revspecs(self):
        self._prepare()
        #self.run_bzr_error(('<?xml version="1.0" encoding="UTF-8"?><error>'
        #    '<class>BzrCommandError</class><dict><key>msg</key><value>'
        #    'Start revision must be older than the end revision.</value>'
        #    '</dict><message>Start revision must be older than the end '
        #    'revision.</message></error>',),
        self.run_bzr_error(('Start revision must be older than '
            'the end revision.',),
                           ['xmllog', '-r3..1'])

    def test_log_revno_n_path(self):
        self._prepare(path='branch1')
        self._prepare(path='branch2')
        log = self.run_bzr("xmllog -r revno:2:branch1..revno:3:branch2",
                          retcode=3)[0]
        log_xml = fromstring(self.run_bzr("xmllog -r revno:1:branch2..revno:3:branch2")[0])
        self.assertEqualDiff(elementtree_tostring(self.full_log_xml),
                             elementtree_tostring(log_xml))
        log_xml = fromstring(self.run_bzr("xmllog -r revno:1:branch2")[0])
        for revno in log_xml.findall('log/revno'):
            self.assertTrue(revno.text in ['1'])
            self.assertTrue(revno.text not in ['2'])
        for branch_nick in log_xml.findall('log/branch-nick'):
            self.assertTrue(branch_nick.text in ['branch2'])
            self.assertTrue(branch_nick.text not in ['branch1'])

    def test_log_nonexistent_file(self):
        # files that don't exist in either the basis tree or working tree
        # should give an error
        wt = self.make_branch_and_tree('.')
        out, err = self.run_bzr('xmllog does-not-exist', retcode=3)
        self.assertContainsRe(
            err,
            'Path unknown at end or start of revision range: does-not-exist')

    def test_log_with_tags(self):
        tree = self._prepare(format='dirstate-tags')
        branch = tree.branch
        branch.tags.set_tag('tag1', branch.get_rev_id(1))
        branch.tags.set_tag('tag1.1', branch.get_rev_id(1))
        branch.tags.set_tag('tag3', branch.last_revision())

        log_xml = fromstring(self.run_bzr("xmllog -r-1")[0])
        for tag in log_xml.findall('log/tags/tag'):
            self.assertEquals(tag.text, 'tag3')
        #self.assertTrue('tags: tag3' in log)

        log_xml = fromstring(self.run_bzr("xmllog -r1")[0])
        for tag in log_xml.findall('log/tags/tag'):
            self.assertTrue(tag.text in ['tag1', 'tag1.1'])
        # I guess that we can't know the order of tags in the output
        # since dicts are unordered, need to check both possibilities
        #self.assertContainsRe(log, r'tags: (tag1, tag1\.1|tag1\.1, tag1)')

    def test_merged_log_with_tags(self):
        b