#       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.

import os
import allura
from StringIO import StringIO
import logging

import PIL
from alluratest.controller import TestController
from allura.lib import helpers as h
from allura import model as M

from forgediscussion import model as FM

log = logging.getLogger(__name__)


class TestForumAdmin(TestController):

    def setUp(self):
        TestController.setUp(self)
        self.app.get('/discussion/')

    def test_forum_CRUD(self):
        r = self.app.get('/admin/discussion/forums')
        r.forms[3]['add_forum.shortname'] = 'testforum'
        r.forms[3]['add_forum.name'] = 'Test Forum'
        r = r.forms[3].submit().follow()
        assert 'Test Forum' in r
        h.set_context('test', 'Forum', neighborhood='Projects')
        frm = FM.Forum.query.get(shortname='testforum')
        r = self.app.post('/admin/discussion/update_forums',
                          params={'forum-0.delete': '',
                                  'forum-0.id': str(frm._id),
                                  'forum-0.name': 'New Test Forum',
                                  'forum-0.shortname': 'NewTestForum',
                                  'forum-0.description': 'My desc',
                                  'forum-0.monitoring_email': ''})
        r = self.app.get('/admin/discussion/forums')
        assert 'New Test Forum' in r
        assert 'My desc' in r

    def test_forum_CRUD_hier(self):
        r = self.app.get('/admin/discussion/forums')
        r.forms[3]['add_forum.shortname'] = 'testforum'
        r.forms[3]['add_forum.name'] = 'Test Forum'
        r = r.forms[3].submit().follow()
        r = self.app.get('/admin/discussion/forums')
        assert 'testforum' in r
        h.set_context('test', 'discussion', neighborhood='Projects')
        frm = FM.Forum.query.get(shortname='testforum')
        r = self.app.get('/admin/discussion/forums')
        r.forms[3]['add_forum.shortname'] = 'childforum'
        r.forms[3]['add_forum.name'] = 'Child Forum'
        r.forms[3]['add_forum.parent'] = str(frm._id)
        r.forms[3].submit()
        r = self.app.get('/admin/discussion/forums')
        assert 'Child Forum' in r

    def test_bad_forum_names(self):
        r = self.app.get('/admin/discussion/forums')
        r.forms[3]['add_forum.shortname'] = 'Test.Forum'
        r.forms[3]['add_forum.name'] = 'Test Forum'
        r = r.forms[3].submit()
        assert 'error' in r
        r = self.app.get('/admin/discussion/forums')
        r.forms[3]['add_forum.shortname'] = 'Test/Forum'
        r.forms[3]['add_forum.name'] = 'Test Forum'
        r = r.forms[3].submit()
        assert 'error' in r
        r = self.app.get('/admin/discussion/forums')
        r.forms[3]['add_forum.shortname'] = 'Test Forum'
        r.forms[3]['add_forum.name'] = 'Test Forum'
        r = r.forms[3].submit()
        assert 'error' in r

    def test_duplicate_forum_names(self):
        r = self.app.get('/admin/discussion/forums')
        r.forms[3]['add_forum.shortname'] = 'a'
        r.forms[3]['add_forum.name'] = 'Forum A'
        r = r.forms[3].submit()
        r = self.app.get('/admin/discussion/forums')
        r.forms[3]['add_forum.shortname'] = 'b'
        r.forms[3]['add_forum.name'] = 'Forum B'
        r = r.forms[3].submit()
        h.set_context('test', 'Forum', neighborhood='Projects')
        forum_a = FM.Forum.query.get(shortname='a')
        self.app.post('/admin/discussion/update_forums',
                      params={'forum-0.delete': 'on',
                              'forum-0.id': str(forum_a._id),
                              'forum-0.name': 'Forum A',
                              'forum-0.description': ''
                              })
        # Now we have two forums: 'a', and 'b'.  'a' is deleted.
        # Let's try to create new forums with these names.
        r = self.app.get('/admin/discussion/forums')
        r.forms[3]['add_forum.shortname'] = 'a'
        r.forms[3]['add_forum.name'] = 'Forum A'
        r = r.forms[3].submit()
        assert 'error' in r
        r = self.app.get('/admin/discussion/forums')
        r.forms[3]['add_forum.shortname'] = 'b'
        r.forms[3]['add_forum.name'] = 'Forum B'
        r = r.forms[3].submit()
        assert 'error' in r

    def test_delete_undelete(self):
        r = self.app.get('/admin/discussion/forums')
        r = self.app.get('/admin/discussion/forums')
        r.forms[3]['add_forum.shortname'] = 'testforum'
        r.forms[3]['add_forum.name'] = 'Test Forum'
        r = r.forms[3].submit()
        r = self.app.get('/admin/discussion/forums')
        soup_form = r.html.find('form', action='update_forums')
        assert len(soup_form.findAll('input', {'value': 'Delete'})) == 2
        h.set_context('test', 'Forum', neighborhood='Projects')
        frm = FM.Forum.query.get(shortname='testforum')

        r = self.app.post('/admin/discussion/update_forums',
                          params={'forum-0.delete': 'on',
                                  'forum-0.id': str(frm._id),
                                  'forum-0.name': 'New Test Forum',
                                  'forum-0.description': 'My desc'})
        r = self.app.get('/admin/discussion/forums')
        soup_form = r.html.find('form', action='update_forums')
        assert len(soup_form.findAll('input', {'value': 'Delete'})) == 1
        r = self.app.post('/admin/discussion/update_forums',
                          params={'forum-0.undelete': 'on',
                                  'forum-0.id': str(frm._id),
                                  'forum-0.name': 'New Test Forum',
                                  'forum-0.description': 'My desc'})
        r = self.app.get('/admin/discussion/forums')
        soup_form = r.html.find('form', action='update_forums')
        assert len(soup_form.findAll('input', {'value': 'Delete'})) == 2

    def test_members_only(self):
        # make a forum anyone can see
        r = self.app.get('/admin/discussion/forums')
        r.forms[3]['add_forum.shortname'] = 'secret'
        r.forms[3]['add_forum.name'] = 'Secret'
        r.forms[3].submit()
        # forum can be viewed by member and non-member
        self.app.get('/discussion/secret')
        self.app.get('/discussion/secret',
                     extra_environ=dict(username='test-user'))
        # make a post in the forum and confirm it is also viewable by member
        # and non-member
        r = self.app.get('/discussion/create_topic/')
        f = r.html.find(
            'form', {'action': '/p/test/discussion/save_new_topic'})
        params = dict()
        inputs = f.findAll('input')
        for field in inputs:
            if field.has_key('name'):  # nopep8 - beautifulsoup3 actually uses has_key
                params[field['name']] = field.get('value') or ''
        params[f.find('textarea')['name']] = 'secret text'
        params[f.find('select')['name']] = 'secret'
        params[f.find('input', {'style': 'width: 90%'})
               ['name']] = 'secret topic'
        r = self.app.post('/discussion/save_new_topic', params=params).follow()
        thread_url = r.request.url
        self.app.get(thread_url)
        self.app.get(thread_url, extra_environ=dict(username='test-user'))
        # link shows up in app for member and non-member
        r = self.app.get('/discussion/')
        assert '/secret/' in r
        r = self.app.get('/discussion/',
                         extra_environ=dict(username='test-user'))
        assert '/secret/' in r
        # make the forum member only viewable
        secret = FM.Forum.query.get(shortname='secret')
        self.app.post('/admin/discussion/update_forums',
                      params={'forum-0.members_only': 'on',
                              'forum-0.id': str(secret._id),
                              'forum-0.name': 'Secret',
                              'forum-0.shortname': 'secret',
                              'forum-0.description': '',
                              'forum-0.monitoring_email': ''
                              })
        # member can see the forum, but non-member gets 403
        self.app.get('/discussion/secret')
        self.app.get('/discussion/secret',
                     extra_environ=dict(username='test-user'), status=403)
        # member can see a thread in the forum, but non-member gets 403
        self.app.get(thread_url)
        self.app.get(thread_url,
                     extra_environ=dict(username='test-user'), status=403)
        # link shows up in app for member but not non-member
        r = self.app.get('/discussion/')
        assert '/secret/' in r
        r = self.app.get('/discussion/',
                         extra_environ=dict(username='test-user'))
        assert '/secret/' not in r

    def test_anon_posts(self):
        # make a forum anons can't post in
        r = self.app.get('/admin/discussion/forums')
        r.forms[3]['add_forum.shortname'] = 'testforum'
        r.forms[3]['add_forum.name'] = 'Test Forum'
        r.forms[3].submit()
        # try to post in the forum and get a 403
        r = self.app.get('/discussion/create_topic/')
        f = r.html.find(
            'form', {'action': '/p/test/discussion/save_new_topic'})
        params = dict()
        inputs = f.findAll('input')
        for field in inputs:
            if field.has_key('name'):  # nopep8 - beautifulsoup3 actually uses has_key
                params[field['name']] = field.get('value') or ''
        params[f.find('textarea')['name']] = 'post text'
        params[f.find('select')['name']] = 'testforum'
        params[f.find('input', {'style': 'width: 90%'})['name']] = 'post topic'
        r = self.app.post('/discussion/save_new_topic',
                          params=params, extra_environ=dict(username='*anonymous'))
        assert r.location == 'http://localhost/auth/'
        # allow anon posts in the forum
        testforum = FM.Forum.query.get(shortname='testforum')
        self.app.post('/admin/discussion/update_forums',
                      params={'forum-0.anon_posts': 'on',
                              'forum-0.id': str(testforum._id),
                              'forum-0.name': 'Test Forum',
                              'forum-0.shortname': 'testforum',
                              'forum-0.description': '',
                              'forum-0.monitoring_email': ''
                              })
        # successfully post to the forum
        r = self.app.get('/discussion/create_topic/')
        f = r.html.find(
            'form', {'action': '/p/test/discussion/save_new_topic'})
        params = dict()
        inputs = f.findAll('input')
        for field in inputs:
            if field.has_key('name'):  # nopep8 - beautifulsoup3 actually uses has_key
                params[field['name']] = field.get('value') or ''
        params[f.find('textarea')['name']] = 'post text'
        params[f.find('select')['name']] = 'testforum'
        params[f.find('input', {'style': 'width: 90%'})['name']] = 'post topic'
        r = self.app.post('/discussion/save_new_topic', params=params)
        assert 'http://localhost/p/test/discussion/testforum/thread/' in r.location

    def test_footer_monitoring_email(self):
        r = self.app.get('/admin/discussion/forums')
        r.forms[3]['add_forum.shortname'] = 'testforum'
        r.forms[3]['add_forum.name'] = 'Test Forum'
        r.forms[3].submit()
        testforum = FM.Forum.query.get(shortname='testforum')
        self.app.post('/admin/discussion/update_forums',
                      params={'forum-0.anon_posts': 'on',
                              'forum-0.id': str(testforum._id),
                              'forum-0.name': 'Test Forum',
                              'forum-0.shortname': 'testforum',
                              'forum-0.description': '',
                              'forum-0.monitoring_email': 'email@monitoring.com'
                              })

        r = self.app.get('/discussion/create_topic/')
        f = r.html.find(
            'form', {'action': '/p/test/discussion/save_new_topic'})
        params = dict()
        inputs = f.findAll('input')
        for field in inputs:
            if field.has_key('name'):  # nopep8 - beautifulsoup3 actually uses has_key
                params[field['name']] = field.get('value') or ''
        params[f.find('textarea')['name']] = 'post text'
        params[f.find('select')['name']] = 'testforum'
        params[f.find('input', {'style': 'width: 90%'})['name']] = 'post topic'
        r = self.app.post('/discussion/save_new_topic', params=params)
        M.MonQTask.run_ready()
        email_tasks = M.MonQTask.query.find(
            dict(task_name='allura.tasks.mail_tasks.sendsimplemail')).all()
        assert 'Sent from localhost because email@monitoring.com is subscribed '\
               'to http://localhost/p/test/discussion/testforum/' in email_tasks[
            0].kwargs['text'], email_tasks[0].kwargs['text']
        assert 'a project admin can change settings at http://localhost/p/test/admin/discussion/forums' in email_tasks[
            0].kwargs['text']
