#       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 tg import tmpl_context as c

from mock import patch
from tg import config

from allura.lib import helpers as h
from allura.tests import decorators as td
from allura import model as M
from alluratest.controller import TestRestApiBase

from forgetracker import model as TM


class TestTrackerApiBase(TestRestApiBase):

    def setup_method(self, method):
        super().setup_method(method)
        self.setup_with_tools()

    @td.with_tool('test', 'Tickets', 'bugs',
                  TicketMonitoringEmail='test@localhost',
                  TicketMonitoringType='AllTicketChanges')
    def setup_with_tools(self):
        h.set_context('test', 'bugs', neighborhood='Projects')
        self.tracker_globals = c.app.globals

    def create_ticket(self, summary=None, status=None):
        return self.api_post(
            '/rest/p/test/bugs/new',
            wrap_args='ticket_form',
            params=dict(
                summary=summary or 'test new ticket',
                status=self.tracker_globals.open_status_names.split()[0],
                labels='',
                description='',
                assigned_to='',
                **{'custom_fields._milestone': ''}),
            status=status)


class TestRestNewTicket(TestTrackerApiBase):

    def test_new_ticket(self):
        summary = 'test new ticket'
        ticket_view = self.api_post(
            '/rest/p/test/bugs/new',
            wrap_args='ticket_form',
            params=dict(
                summary=summary,
                status=self.tracker_globals.open_status_names.split()[0],
                labels='foo,bar',
                description='descr',
                assigned_to='',
                **{'custom_fields._milestone': ''}
            ))
        json = ticket_view.json['ticket']
        assert json['status'] == 'open', json
        assert json['summary'] == 'test new ticket', json
        assert json['reported_by'] == 'test-admin'
        assert json['labels'] == ['foo', 'bar'], json
        assert json['description'] == 'descr', json
        assert json['private'] is False, json

    def test_invalid_ticket(self):
        self.app.get('/rest/p/test/bugs/2', status=404)

    def test_create_limit(self):
        self.create_ticket(summary='First ticket')
        # Set rate limit to unlimit
        with h.push_config(config, **{'forgetracker.rate_limits': '{}'}):
            summary = 'Second ticket'
            self.create_ticket(summary=summary)
            t = TM.Ticket.query.get(summary=summary)
            assert t != None
        # Set rate limit to 1 in first hour of project
        with h.push_config(config, **{'forgetracker.rate_limits': '{"3600": 1}'}):
            summary = 'Third ticket'
            self.create_ticket(summary=summary, status=429)
            t = TM.Ticket.query.get(summary=summary)
            assert t == None


class TestRestUpdateTicket(TestTrackerApiBase):

    def setup_method(self, method):
        super().setup_method(method)
        ticket_view = self.create_ticket()
        self.ticket_args = ticket_view.json['ticket']

    def test_update_ticket(self):
        args = dict(self.ticket_args, summary='test update ticket', labels='',
                    assigned_to=self.ticket_args['assigned_to_id'] or '')
        for bad_key in ('ticket_num', 'assigned_to_id', 'created_date',
                        'reported_by', 'reported_by_id', '_id', 'votes_up', 'votes_down', 'discussion_thread'):
            del args[bad_key]
        args['private'] = str(args['private'])
        args['discussion_disabled'] = str(args['discussion_disabled'])
        ticket_view = self.api_post(
            '/rest/p/test/bugs/1/save', wrap_args='ticket_form', params=h.encode_keys(args))
        assert ticket_view.status_int == 200, ticket_view.showbrowser()
        json = ticket_view.json['ticket']
        assert int(json['ticket_num']) == 1
        assert json['summary'] == 'test update ticket', json


class TestRestIndex(TestTrackerApiBase):

    def setup_method(self, method):
        super().setup_method(method)
        self.create_ticket()

    def test_ticket_index(self):
        tickets = self.api_get('/rest/p/test/bugs/')
        assert len(tickets.json['tickets']) == 1, tickets.json
        assert (tickets.json['tickets'][0]
                == dict(ticket_num=1, summary='test new ticket')), tickets.json['tickets'][0]
        assert tickets.json['tracker_config']['options']['mount_point'] == 'bugs'
        assert tickets.json['tracker_config']['options']['TicketMonitoringType'] == 'AllTicketChanges'
        assert tickets.json['tracker_config']['options']['EnableVoting']
        assert tickets.json['tracker_config']['options']['TicketMonitoringEmail'] == 'test@localhost'
        assert tickets.json['tracker_config']['options']['mount_label'] == 'Tickets'
        assert tickets.json['saved_bins'][0]['sort'] == 'mod_date_dt desc'
        assert tickets.json['saved_bins'][0]['terms'] == '!status:closed && !status:wont-fix'
        assert tickets.json['saved_bins'][0]['summary'] == 'Changes'
        assert len(tickets.json['saved_bins'][0]) == 4
        assert tickets.json['milestones'][0]['name'] == '1.0'
        assert tickets.json['milestones'][1]['name'] == '2.0'

    def test_ticket_index_noauth(self):
        tickets = self.api_get('/rest/p/test/bugs', user='*anonymous')
        assert 'TicketMonitoringEmail' not in tickets.json[
            'tracker_config']['options']
        # make sure it didn't get removed from the db too
        ticket_config = M.AppConfig.query.get(
            project_id=c.project._id, tool_name='tickets')
        assert (ticket_config.options.get('TicketMonitoringEmail') ==
                     'test@localhost')

    @td.with_tool('test', 'Tickets', 'dummy')
    def test_move_ticket_redirect(self):
        p = M.Project.query.get(shortname='test')
        dummy_tracker = p.app_instance('dummy')
        self.app.post(
            '/p/test/bugs/1/move',
            params={'tracker': str(dummy_tracker.config._id)}).follow()

        ticket = self.api_get('/rest/p/test/bugs/1/')
        assert ticket.request.path == '/rest/p/test/dummy/1/'


class TestRestDiscussion(TestTrackerApiBase):

    def setup_method(self, method):
        super().setup_method(method)
        ticket_view = self.create_ticket()
        self.ticket_args = ticket_view.json['ticket']

    def test_post(self):
        r = self.api_get('/rest/p/test/bugs/1/')
        thread_id = r.json['ticket']['discussion_thread']['_id']
        post = self.api_post(
            '/rest/p/test/bugs/_discuss/thread/%s/new' % thread_id,
            text='This is a comment', wrap_args=None)
        thread = self.api_get('/rest/p/test/bugs/_discuss/thread/%s/' % thread_id)
        assert len(thread.json['thread']['posts']) == 1, thread.json
        assert post.json['post']['text'] == 'This is a comment', post.json
        reply = self.api_post(
            '/rest/p/test/bugs/_discuss/thread/{}/{}/reply'.format(thread.json['thread']
                                                               ['_id'], post.json['post']['slug']),
            text='This is a reply', wrap_args=None)
        assert reply.json['post']['text'] == 'This is a reply', reply.json
        thread = self.api_get('/rest/p/test/bugs/_discuss/thread/%s/' % thread_id)
        assert len(thread.json['thread']['posts']) == 2, thread.json


class TestRestSearch(TestTrackerApiBase):

    @property
    def ticket(self):
        return TM.Ticket(
            ticket_num=5,
            summary='our test ticket',
            status='open',
            labels=['tiny', 'minor'])

    @patch('forgetracker.model.Ticket.paged_search')
    def test_no_criteria(self, paged_search):
        paged_search.return_value = dict(tickets=[self.ticket])
        r = self.api_get('/rest/p/test/bugs/search')
        assert r.status_int == 200
        assert r.json['tickets'][0]['summary'] == 'our test ticket'
        assert r.json['tickets'][0]['ticket_num'] == 5
        assert r.json['tickets'][0]['status'] == 'open'
        assert r.json['tickets'][0]['labels'] == ['tiny', 'minor']
        assert 'description' not in r.json
        assert 'discussion_thread' not in r.json

    @patch('forgetracker.model.Ticket.paged_search')
    def test_some_criteria(self, paged_search):
        q = 'labels:testing && status:open'
        paged_search.return_value = dict(
            tickets=[self.ticket],
            sort='status',
            limit=2,
            count=1,
            page=0,
            q=q,
        )
        r = self.api_get('/rest/p/test/bugs/search',
                         q=q, sort='status', limit='2')
        assert r.status_int == 200
        assert r.json['limit'] == 2
        assert r.json['q'] == q
        assert r.json['sort'] == 'status'
        assert r.json['count'] == 1
        assert r.json['page'] == 0
        assert r.json['tickets'][0]['summary'] == 'our test ticket'
        assert r.json['tickets'][0]['ticket_num'] == 5
        assert r.json['tickets'][0]['status'] == 'open'
        assert r.json['tickets'][0]['labels'] == ['tiny', 'minor']
        assert 'description' not in r.json
        assert 'discussion_thread' not in r.json


class TestRestHasAccess(TestTrackerApiBase):

    def test_has_access_no_params(self):
        self.api_get('/rest/p/test/bugs/has_access', status=404)
        self.api_get('/rest/p/test/bugs/has_access?user=root', status=404)
        self.api_get('/rest/p/test/bugs/has_access?perm=read', status=404)

    def test_has_access_unknown_params(self):
        """Unknown user and/or permission always False for has_access API"""
        r = self.api_get(
            '/rest/p/test/bugs/has_access?user=babadook&perm=read',
            user='root')
        assert r.status_int == 200
        assert r.json['result'] == False
        r = self.api_get(
            '/rest/p/test/bugs/has_access?user=test-user&perm=jump',
            user='root')
        assert r.status_int == 200
        assert r.json['result'] == False

    def test_has_access_not_admin(self):
        """
        User which has no 'admin' permission on neighborhood can't use
        has_access API
        """
        self.api_get(
            '/rest/p/test/bugs/has_access?user=test-admin&perm=admin',
            user='test-user',
            status=403)

    def test_has_access(self):
        r = self.api_get(
            '/rest/p/test/bugs/has_access?user=test-admin&perm=delete',
            user='root')
        assert r.status_int == 200
        assert r.json['result'] == True
        r = self.api_get(
            '/rest/p/test/bugs/has_access?user=test-user&perm=delete',
            user='root')
        assert r.status_int == 200
        assert r.json['result'] == False
