#       Licensed to the Apache Software Foundation (ASF) under one
#       or more contributor license agreements.  See the NOTICE file
#       distributed with this work for additional information
#       regarding copyright ownership.  The ASF licenses this file
#       to you under the Apache License, Version 2.0 (the
#       "License"); you may not use this file except in compliance
#       with the License.  You may obtain a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#       Unless required by applicable law or agreed to in writing,
#       software distributed under the License is distributed on an
#       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
#       KIND, either express or implied.  See the License for the
#       specific language governing permissions and limitations
#       under the License.

from unittest import TestCase
import pkg_resources

import mock
from datadiff.tools import assert_equal

from forgeimporters import google
from forgeimporters import base


class TestGoogleCodeProjectExtractor(TestCase):
    def setUp(self):
        self._p_urlopen = mock.patch.object(base.ProjectExtractor, 'urlopen')
        # self._p_soup = mock.patch.object(google, 'BeautifulSoup')
        self._p_soup = mock.patch.object(base, 'BeautifulSoup')
        self.urlopen = self._p_urlopen.start()
        self.soup = self._p_soup.start()
        self.project = mock.Mock(name='project')
        self.project.get_tool_data.return_value = 'my-project'

    def tearDown(self):
        for patcher in ('_p_urlopen', '_p_soup'):
            try:
                getattr(self, patcher).stop()
            except RuntimeError as e:
                if 'unstarted patcher' in str(e):
                    pass  # test case might stop them early
                else:
                    raise

    def test_init(self):
        extractor = google.GoogleCodeProjectExtractor('my-project', 'project_info')

        self.urlopen.assert_called_once_with('http://code.google.com/p/my-project/')
        self.soup.assert_called_once_with(self.urlopen.return_value)
        self.assertEqual(extractor.page, self.soup.return_value)

    def test_get_page(self):
        extractor = google.GoogleCodeProjectExtractor('my-project', 'project_info')
        self.assertEqual(1, self.urlopen.call_count)
        page = extractor.get_page('project_info')
        self.assertEqual(1, self.urlopen.call_count)
        self.assertEqual(page, extractor._page_cache['http://code.google.com/p/my-project/'])
        page = extractor.get_page('project_info')
        self.assertEqual(1, self.urlopen.call_count)
        self.assertEqual(page, extractor._page_cache['http://code.google.com/p/my-project/'])
        page = extractor.get_page('source_browse')
        self.assertEqual(2, self.urlopen.call_count)
        self.assertEqual(page, extractor._page_cache['http://code.google.com/p/my-project/source/browse/'])
        parser = mock.Mock(return_value='parsed')
        page = extractor.get_page('url', parser=parser)
        self.assertEqual(page, 'parsed')
        self.assertEqual(page, extractor._page_cache['url'])

    def test_get_page_url(self):
        extractor = google.GoogleCodeProjectExtractor('my-project')
        self.assertEqual(extractor.get_page_url('project_info'),
                'http://code.google.com/p/my-project/')

    def test_get_short_description(self):
        extractor = google.GoogleCodeProjectExtractor('my-project', 'project_info')
        extractor.page.find.return_value.string = 'My Super Project'

        extractor.get_short_description(self.project)

        extractor.page.find.assert_called_once_with(itemprop='description')
        self.assertEqual(self.project.short_description, 'My Super Project')

    @mock.patch.object(google, 'File')
    @mock.patch.object(google, 'M')
    def test_get_icon(self, M, File):
        File.return_value.type = 'image/png'
        File.return_value.file = 'data'
        extractor = google.GoogleCodeProjectExtractor('my-project', 'project_info')
        extractor.page.find.return_value.get.return_value = 'http://example.com/foo/bar/my-logo.png'

        extractor.get_icon(self.project)

        extractor.page.find.assert_called_once_with(itemprop='image')
        File.assert_called_once_with('http://example.com/foo/bar/my-logo.png', 'my-logo.png')
        M.ProjectFile.save_image.assert_called_once_with(
            'my-logo.png', 'data', 'image/png', square=True,
            thumbnail_size=(48,48), thumbnail_meta={
                'project_id': self.project._id, 'category': 'icon'})

    @mock.patch.object(google, 'M')
    def test_get_license(self, M):
        self.project.trove_license = []
        extractor = google.GoogleCodeProjectExtractor('my-project', 'project_info')
        extractor.page.find.return_value.findNext.return_value.find.return_value.string = '  New BSD License  '
        trove = M.TroveCategory.query.get.return_value

        extractor.get_license(self.project)

        extractor.page.find.assert_called_once_with(text='Code license')
        extractor.page.find.return_value.findNext.assert_called_once_with()
        extractor.page.find.return_value.findNext.return_value.find.assert_called_once_with('a')
        self.assertEqual(self.project.trove_license, [trove._id])
        M.TroveCategory.query.get.assert_called_once_with(fullname='BSD License')

        M.TroveCategory.query.get.reset_mock()
        extractor.page.find.return_value.findNext.return_value.find.return_value.string = 'non-existant license'
        extractor.get_license(self.project)
        M.TroveCategory.query.get.assert_called_once_with(fullname='Other/Proprietary License')

    def _make_extractor(self, html):
        from BeautifulSoup import BeautifulSoup
        with mock.patch.object(base.ProjectExtractor, 'urlopen'):
            extractor = google.GoogleCodeProjectExtractor('my-project')
        extractor.page = BeautifulSoup(html)
        extractor.get_page = lambda pagename: extractor.page
        extractor.url="http://test/source/browse"
        return extractor

    def test_get_repo_type_happy_path(self):
        extractor = self._make_extractor(
                '<span id="crumb_root">\nsvn/&nbsp;</span>')
        self.assertEqual('svn', extractor.get_repo_type())

    def test_get_repo_type_no_crumb_root(self):
        extractor = self._make_extractor('')
        with self.assertRaises(Exception) as cm:
            extractor.get_repo_type()
        self.assertEqual(str(cm.exception),
                "Couldn't detect repo type: no #crumb_root in "
                "http://test/source/browse")

    def test_get_repo_type_unknown_repo_type(self):
        extractor = self._make_extractor(
                '<span id="crumb_root">cvs</span>')
        with self.assertRaises(Exception) as cm:
            extractor.get_repo_type()
        self.assertEqual(str(cm.exception), "Unknown repo type: cvs")

    def test_empty_issue(self):
        empty_issue = open(pkg_resources.resource_filename('forgeimporters', 'tests/data/google/empty-issue.html')).read()
        gpe = self._make_extractor(empty_issue)
        self.assertIsNone(gpe.get_issue_owner())
        self.assertEqual(gpe.get_issue_status(), '')
        self.assertEqual(gpe.get_issue_attachments(), [])
        self.assertEqual(list(gpe.iter_comments()), [])
        self.assertEqual(gpe.get_issue_mod_date(), 'Thu Aug  8 14:56:23 2013')

    def test_get_issue_basic_fields(self):
        test_issue = open(pkg_resources.resource_filename('forgeimporters', 'tests/data/google/test-issue.html')).read()
        gpe = self._make_extractor(test_issue)
        self.assertEqual(gpe.get_issue_creator().name, 'john...@gmail.com')
        self.assertEqual(gpe.get_issue_creator().url, 'http://code.google.com/u/101557263855536553789/')
        self.assertEqual(gpe.get_issue_owner().name, 'john...@gmail.com')
        self.assertEqual(gpe.get_issue_owner().url, 'http://code.google.com/u/101557263855536553789/')
        self.assertEqual(gpe.get_issue_status(), 'Started')
        self._p_soup.stop()
        self.assertEqual(gpe.get_issue_summary(), 'Test "Issue"')
        assert_equal(gpe.get_issue_description(),
                'Test *Issue* for testing\n'
                '\n'
                '  1. Test List\n'
                '  2. Item\n'
                '\n'
                '**Testing**\n'
                '\n'
                ' * Test list 2\n'
                ' * Item\n'
                '\n'
                '# Test Section\n'
                '\n'
                '    p = source.test_issue.post()\n'
                '    p.count = p.count *5 #* 6\n'
                '    if p.count &gt; 5:\n'
                '        print "Not &lt; 5 &amp; != 5"\n'
                '\n'
                'That\'s all'
            )
        self.assertEqual(gpe.get_issue_created_date(), 'Thu Aug  8 15:33:52 2013')
        self.assertEqual(gpe.get_issue_stars(), 1)

    def test_get_issue_mod_date(self):
        test_issue = open(pkg_resources.resource_filename('forgeimporters', 'tests/data/google/test-issue.html')).read()
        gpe = self._make_extractor(test_issue)
        self.assertEqual(gpe.get_issue_mod_date(), 'Thu Aug  8 15:36:57 2013')

    def test_get_issue_labels(self):
        test_issue = open(pkg_resources.resource_filename('forgeimporters', 'tests/data/google/test-issue.html')).read()
        gpe = self._make_extractor(test_issue)
        self.assertEqual(gpe.get_issue_labels(), [
                'Type-Defect',
                'Priority-Medium',
                'Milestone-Release1.0',
                'OpSys-All',
                'Component-Logic',
                'Performance',
                'Security',
                'OpSys-Windows',
                'OpSys-OSX',
            ])

    @mock.patch.object(base, 'StringIO')
    def test_get_issue_attachments(self, StringIO):
        self.urlopen.return_value.info.return_value = {'content-type': 'text/plain; foo'}
        test_issue = open(pkg_resources.resource_filename('forgeimporters', 'tests/data/google/test-issue.html')).read()
        gpe = self._make_extractor(test_issue)
        attachments = gpe.get_issue_attachments()
        self.assertEqual(len(attachments), 1)
        self.assertEqual(attachments[0].filename, 'at1.txt')
        self.assertEqual(attachments[0].url, 'http://allura-google-importer.googlecode.com/issues/attachment?aid=70000000&name=at1.txt&token=3REU1M3JUUMt0rJUg7ldcELt6LA%3A1376059941255')
        self.assertEqual(attachments[0].type, 'text/plain')

    @mock.patch.object(base, 'StringIO')
    def test_iter_comments(self, StringIO):
        test_issue = open(pkg_resources.resource_filename('forgeimporters', 'tests/data/google/test-issue.html')).read()
        gpe = self._make_extractor(test_issue)
        comments = list(gpe.iter_comments())
        self.assertEqual(len(comments), 4)
        expected = [
                {
                    'author.name': 'john...@gmail.com',
                    'author.url': 'http://code.google.com/u/101557263855536553789/',
                    'created_date': 'Thu Aug  8 15:35:15 2013',
                    'body': 'Test *comment* is a comment',
                    'updates': {'Status:': 'Started', 'Labels:': '-OpSys-Linux OpSys-Windows'},
                    'attachments': ['at2.txt'],
                },
                {
                    'author.name': 'john...@gmail.com',
                    'author.url': 'http://code.google.com/u/101557263855536553789/',
                    'created_date': 'Thu Aug  8 15:35:34 2013',
                    'body': 'Another comment',
                    'updates': {},
                    'attachments': [],
                },
                {
                    'author.name': 'john...@gmail.com',
                    'author.url': 'http://code.google.com/u/101557263855536553789/',
                    'created_date': 'Thu Aug  8 15:36:39 2013',
                    'body': 'Last comment',
                    'updates': {},
                    'attachments': ['at4.txt', 'at1.txt'],
                },
                {
                    'author.name': 'john...@gmail.com',
                    'author.url': 'http://code.google.com/u/101557263855536553789/',
                    'created_date': 'Thu Aug  8 15:36:57 2013',
                    'body': 'Oh, I forgot one',
                    'updates': {'Labels:': 'OpSys-OSX'},
                    'attachments': [],
                },
            ]
        for actual, expected in zip(comments, expected):
            self.assertEqual(actual.author.name, expected['author.name'])
            self.assertEqual(actual.author.url, expected['author.url'])
            self.assertEqual(actual.created_date, expected['created_date'])
            self.assertEqual(actual.body, expected['body'])
            self.assertEqual(actual.updates, expected['updates'])
            self.assertEqual([a.filename for a in actual.attachments], expected['attachments'])

class TestUserLink(TestCase):
    def test_plain(self):
        tag = mock.Mock()
        tag.string.strip.return_value = 'name'
        tag.get.return_value = None
        link = google.UserLink(tag)
        self.assertEqual(str(link), 'name')

    def test_linked(self):
        tag = mock.Mock()
        tag.string.strip.return_value = 'name'
        tag.get.return_value = '/p/project'
        link = google.UserLink(tag)
        self.assertEqual(str(link), '[name](http://code.google.com/p/project)')


class TestComment(TestCase):
    html = """
    <div class="cursor_off vt issuecomment" id="hc2">
     <div style="float:right; margin-right:.3em; text-align:right">
     <span class="date" title="Tue Jun 25 03:20:09 2013">
     Jun 25, 2013
     </span>
     </div>
     <span class="author">
     <span class="role_label">Project Member</span>
     <a name="c2" href="/p/pychess/issues/detail?id=267#c2">#2</a>
     <a class="userlink" href="/u/gbtami/">gbtami</a></span>
    <pre><i>(No comment was entered for this change.)</i>
    </pre>
     <div class="updates">
     <div class="round4"></div>
     <div class="round2"></div>
     <div class="round1"></div>
     <div class="box-inner">
     <b>Summary:</b>
     Make PyChess keyboard accessible
     <span class="oldvalue">
     (was: Make PyChess keyboard accecible)
     </span>
     <br>
     <b>Status:</b>
     Accepted
     <br>
     </div>
     <div class="round1"></div>
     <div class="round2"></div>
     <div class="round4"></div>
     </div>
    </div>
    """

    def test_init(self):
        from BeautifulSoup import BeautifulSoup
        html = BeautifulSoup(self.html)
        comment = google.Comment(html.find('div', 'issuecomment'))
        self.assertEqual(comment.updates, {
            u'Summary:': u'Make PyChess keyboard accessible',
            u'Status:': u'Accepted',
            })
