#       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
import mock
from ming.base import Object
from alluratest.tools import assert_equal, assert_raises
from formencode import validators as fev

from alluratest.controller import setup_unit_test
from allura import app
from allura.lib.app_globals import Icon
from allura.lib import mail_util


def setUp():
    setup_unit_test()
    c.user._id = None
    c.project = mock.Mock()
    c.project.name = 'Test Project'
    c.project.shortname = 'tp'
    c.project._id = 'testproject/'
    c.project.url = lambda: '/testproject/'
    app_config = mock.Mock()
    app_config._id = None
    app_config.project_id = 'testproject/'
    app_config.tool_name = 'tool'
    app_config.options = Object(mount_point='foo')
    c.app = mock.Mock()
    c.app.config = app_config
    c.app.config.script_name = lambda: '/testproject/test_application/'
    c.app.config.url = lambda: 'http://testproject/test_application/'
    c.app.url = c.app.config.url()
    c.app.__version__ = '0.0'


def test_config_options():
    options = [
        app.ConfigOption('test1', str, 'MyTestValue'),
        app.ConfigOption('test2', str, lambda:'MyTestValue')]
    assert options[0].default == 'MyTestValue'
    assert options[1].default == 'MyTestValue'


def test_config_options_render_attrs():
    opt = app.ConfigOption('test1', str, None, extra_attrs={'type': 'url'})
    assert_equal(opt.render_attrs(), 'type="url"')


def test_config_option_without_validator():
    opt = app.ConfigOption('test1', str, None)
    assert_equal(opt.validate(None), None)
    assert_equal(opt.validate(''), '')
    assert_equal(opt.validate('val'), 'val')


def test_config_option_with_validator():
    v = fev.NotEmpty()
    opt = app.ConfigOption('test1', str, None, validator=v)
    assert_equal(opt.validate('val'), 'val')
    assert_raises(fev.Invalid, opt.validate, None)
    assert_raises(fev.Invalid, opt.validate, '')


def test_options_on_install_default():
    a = app.Application(c.project, c.app.config)
    assert_equal(a.options_on_install(), [])


def test_options_on_install():
    opts = [app.ConfigOption('url', str, None),
            app.ConfigOption('private', bool, None)]
    class TestApp(app.Application):
        config_options = app.Application.config_options + opts + [
            app.ConfigOption('not_on_install', str, None),
        ]
        config_on_install = ['url', 'private']

    a = TestApp(c.project, c.app.config)
    assert_equal(a.options_on_install(), opts)


def test_main_menu():
    class TestApp(app.Application):
        @property
        def sitemap(self):
            children = [app.SitemapEntry('New', 'new', ui_icon=Icon('some-icon')),
                        app.SitemapEntry('Recent', 'recent'),
                        ]
            return [app.SitemapEntry('My Tool', '.')[children]]

    a = TestApp(c.project, c.app.config)
    main_menu = a.main_menu()
    assert_equal(len(main_menu), 1)
    assert_equal(main_menu[0].children, [])  # default main_menu implementation should drop the children from sitemap()


def test_sitemap():
    sm = app.SitemapEntry('test', '')[
        app.SitemapEntry('a', 'a/'),
        app.SitemapEntry('b', 'b/')]
    sm[app.SitemapEntry(lambda app:app.config.script_name(), 'c/')]
    bound_sm = sm.bind_app(c.app)
    assert bound_sm.url == 'http://testproject/test_application/', bound_sm.url
    assert bound_sm.children[
        -1].label == '/testproject/test_application/', bound_sm.children[-1].label
    assert len(sm.children) == 3
    sm.extend([app.SitemapEntry('a', 'a/')[
        app.SitemapEntry('d', 'd/')]])
    assert len(sm.children) == 3


@mock.patch('allura.app.Application.PostClass.query.get')
def test_handle_artifact_unicode(qg):
    """
    Tests that app.handle_artifact_message can accept utf strings
    """
    ticket = mock.MagicMock()
    ticket.get_discussion_thread.return_value = (mock.MagicMock(), mock.MagicMock())
    post = mock.MagicMock()
    qg.return_value = post

    a = app.Application(c.project, c.app.config)

    msg = dict(payload='foo ƒ†©¥˙¨ˆ'.encode(), message_id=1, headers={})
    a.handle_artifact_message(ticket, msg)
    assert_equal(post.attach.call_args[0][1].getvalue(), 'foo ƒ†©¥˙¨ˆ'.encode())

    msg = dict(payload=b'foo', message_id=1, headers={})
    a.handle_artifact_message(ticket, msg)
    assert_equal(post.attach.call_args[0][1].getvalue(), b'foo')

    msg = dict(payload="\x94my quote\x94".encode(), message_id=1, headers={})
    a.handle_artifact_message(ticket, msg)
    assert_equal(post.attach.call_args[0][1].getvalue(), '\x94my quote\x94'.encode())

    # assert against prod example
    msg_raw = """Message-Id: <1502352031.3216858.1068961568.19EF48C6@webmail.messagingengine.com>
From: foo <foo@bar.com>
To: "[forge:site-support]" <15391@site-support.forge.p.re.sf.net>
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Type: multipart/alternative; boundary="_----------=_150235203132168580"
Date: Thu, 10 Aug 2017 10:00:31 +0200
Subject: Re: [forge:site-support] #15391 Unable to join (my own) mailing list
This is a multi-part message in MIME format.
--_----------=_150235203132168580
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset="utf-8"
Hi
--_----------=_150235203132168580
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset="utf-8"
<!DOCTYPE html>
<html><body>Hi</body></html>
--_----------=_150235203132168580--
    """
    msg = mail_util.parse_message(msg_raw)
    for p in [p for p in msg['parts'] if p['payload'] is not None]:
        # filter here mimics logic in `route_email`
        a.handle_artifact_message(ticket, p)
