#       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
from mock import Mock, patch
from ming.odm import ThreadLocalORMSession

from allura.tests import TestController
from allura.tests.decorators import with_tool
from allura import model as M
from alluratest.controller import setup_unit_test
from forgeimporters.github.code import GitHubRepoImporter
from forgeimporters.github import GitHubOAuthMixin


# important to be distinct from 'test' which ForgeGit uses, so that the
# tests can run in parallel and not clobber each other
test_project_with_repo = 'test2'
with_git = with_tool(test_project_with_repo, 'git', 'src', 'git')


class TestGitHubRepoImporter(TestCase):

    def _make_project(self, gh_proj_name=None):
        project = Mock()
        project.get_tool_data.side_effect = lambda *args: gh_proj_name
        return project

    @patch('forgeimporters.github.code.M')
    @patch('forgeimporters.github.code.g')
    @patch('forgeimporters.github.code.GitHubProjectExtractor')
    def test_import_tool_happy_path(self, ghpe, g, M):
        setup_unit_test()
        ghpe.return_value.get_repo_url.return_value = 'http://remote/clone/url/'
        p = self._make_project(gh_proj_name='myproject')
        u = Mock(name='c.user')
        app = p.install_app.return_value
        app.config.options.mount_point = 'code'
        app.url = 'foo'
        GitHubRepoImporter().import_tool(
            p, u, project_name='project_name', user_name='testuser')
        p.install_app.assert_called_once_with(
            'Git',
            mount_point='code',
            mount_label='Code',
            init_from_url='http://remote/clone/url/',
            import_id={'source': 'GitHub', 'project_name': 'testuser/project_name'})
        M.AuditLog.log.assert_called_once_with(
            'import tool code from testuser/project_name on GitHub',
            project=p, user=u, url='foo')
        g.post_event.assert_called_once_with('project_updated')


class TestGitHubImportController(TestController, TestCase):

    @with_git
    def test_index(self):
        r = self.app.get(
            '/p/{}/admin/ext/import/github-repo/'.format(test_project_with_repo))
        self.assertIsNotNone(r.html.find(attrs=dict(name="gh_user_name")))
        self.assertIsNotNone(r.html.find(attrs=dict(name="gh_project_name")))
        self.assertIsNotNone(r.html.find(attrs=dict(name="mount_label")))
        self.assertIsNotNone(r.html.find(attrs=dict(name="mount_point")))

    @with_git
    @patch('forgeimporters.github.requests')
    @patch('forgeimporters.base.import_tool')
    def test_create(self, import_tool, requests):
        requests.head.return_value.status_code = 200
        params = dict(
            gh_user_name='spooky',
            gh_project_name='poop',
            mount_label='mylabel',
            mount_point='mymount',
        )
        r = self.app.post(
            '/p/{}/admin/ext/import/github-repo/create'.format(
                test_project_with_repo),
            params,
            status=302)
        self.assertEqual(
            r.location, 'http://localhost/p/{}/admin/'.format(
                test_project_with_repo))
        self.assertEqual(
            u'mymount', import_tool.post.call_args[1]['mount_point'])
        self.assertEqual(
            u'mylabel', import_tool.post.call_args[1]['mount_label'])
        self.assertEqual(
            u'poop', import_tool.post.call_args[1]['project_name'])
        self.assertEqual(u'spooky', import_tool.post.call_args[1]['user_name'])
        self.assertEqual(requests.head.call_count, 1)

    @with_git
    @patch('forgeimporters.github.requests')
    @patch('forgeimporters.base.import_tool')
    def test_create_limit(self, import_tool, requests):
        requests.head.return_value.status_code = 200
        project = M.Project.query.get(shortname=test_project_with_repo)
        project.set_tool_data('GitHubRepoImporter', pending=1)
        ThreadLocalORMSession.flush_all()
        params = dict(
            gh_user_name='spooky',
            gh_project_name='poop',
            mount_label='mylabel',
            mount_point='mymount',
        )
        r = self.app.post(
            '/p/{}/admin/ext/import/github-repo/create'.format(
                test_project_with_repo),
            params,
            status=302).follow()
        self.assertIn('Please wait and try again', r)
        self.assertEqual(import_tool.post.call_count, 0)

    @with_git
    @patch.object(GitHubOAuthMixin, 'oauth_begin')
    def test_oauth(self, oauth_begin):
        self.app.get(
            '/p/{}/admin/ext/import/github-repo/'.format(test_project_with_repo))
        self.assertEqual(oauth_begin.call_count, 1)
