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

"""Unit and functional test suite for allura."""
from __future__ import unicode_literals
from __future__ import absolute_import
import os
import six.moves.urllib.request
import six.moves.urllib.parse
import six.moves.urllib.error
import json

import mock
import beaker.session
from formencode import variabledecode
from paste.deploy import loadapp
from paste.deploy.converters import asbool
from paste.script.appinstall import SetupCommand
from tg import tmpl_context as c, app_globals as g
from tg import url, request, response, session
import tg
from tg.wsgiapp import RequestLocals
from webob import Response, Request
import ew
from ming.orm import ThreadLocalORMSession
import ming.orm
import pkg_resources

from allura import model as M
from allura.command import CreateTroveCategoriesCommand
import allura.lib.security
from allura.lib.app_globals import Globals
from allura.lib import helpers as h
from allura.websetup.schema import REGISTRY
#from allura.lib.custom_middleware import environ as ENV, MagicalC
from .validation import ValidatingTestApp
import six

DFL_APP_NAME = 'main'

# these are all helpers & base classes, and should never
# be considered test cases when imported into some test module
__test__ = False


def get_config_file(config=None, current_pkg=None):
    if not config:
        config = 'test.ini'
    if not current_pkg:
        current_pkg = 'allura'

    conf_dir = pkg_resources.resource_filename(current_pkg, '..')
    conf_file = os.path.join(conf_dir, config)

    # split on "#" since it could be foo.ini#main
    if not os.path.exists(conf_file.split('#')[0]) and current_pkg != 'allura':
        # if there isn't a forgewiki/test.ini for example, then fall back to regular allura
        conf_dir = pkg_resources.resource_filename('allura', '..')
        conf_file = os.path.join(conf_dir, config)

    if not os.path.exists(conf_file.split('#')[0]):
        raise EnvironmentError('Cannot find .ini config file {}'.format(conf_file))
    else:
        return conf_file


def setup_basic_test(config=None, app_name=DFL_APP_NAME):
    '''
    Create clean environment for running tests, includes mongodb connection with "mim" (mongo-in-memory) and sample
    data created.

    A lightweight alternative is setup_config_test which doesn't bootstrap app data.
    '''
    try:
        conf_dir = tg.config.here
    except AttributeError:
        conf_dir = os.getcwd()
    test_file = os.path.join(conf_dir, get_config_file(config))
    """
    # setup our app, from TG quickstart example:
    from tg.util import Bunch
    from gearbox.commands.setup_app import SetupAppCommand
    cmd = SetupAppCommand(Bunch(options=Bunch(verbose_level=1)), Bunch())
    cmd.run(Bunch(config_file='config:{}'.format(test_file), section_name=None))
    """
    # setup our app without depending on gearbox (we still depend on Paste anyway)
    # uses [paste.app_install] entry point which call our setup_app()
    cmd = SetupCommand('setup-app')
    cmd.run([test_file, '--quiet'])

    ew.TemplateEngine.initialize({})

    # remove unnecessary bootstrap tasks, e.g. search indexing
    M.MonQTask.query.remove({'state': 'ready'})
setup_basic_test.__test__ = False  # sometimes __test__ above isn't sufficient


def setup_functional_test(config=None, app_name=DFL_APP_NAME, current_pkg=None):
    '''Create clean environment for running tests.  Also return WSGI test app'''
    config = get_config_file(config, current_pkg=current_pkg)
    setup_basic_test(config, app_name)
    conf_dir = tg.config.here
    wsgiapp = loadapp('config:%s#%s' % (config, app_name),
                      relative_to=conf_dir)
    return wsgiapp
# sometimes __test__ above isn't sufficient
setup_functional_test.__test__ = False


def setup_unit_test():
    try:
        while True:
            REGISTRY.cleanup()
    except Exception:
        pass
    REGISTRY.prepare()
    REGISTRY.register(ew.widget_context,
                      ew.core.WidgetContext('http', ew.ResourceManager()))
    REGISTRY.register(allura.credentials, allura.lib.security.Credentials())

    # turbogears has its own special magic wired up for its globals, can't use a regular Registry
    tgl = RequestLocals()
    tgl.app_globals = Globals()
    tgl.tmpl_context = mock.Mock()
    tgl.url = lambda: None
    tgl.request = Request.blank('/', remote_addr='127.0.0.1')
    tgl.response = Response()
    tg.request_local.context._push_object(tgl)

    c.model_cache = None
    ThreadLocalORMSession.close_all()
setup_unit_test.__test__ = False  # sometimes __test__ above isn't sufficient


def setup_global_objects():
    setup_unit_test()
    h.set_context('test', 'wiki', neighborhood='Projects')
    c.user = M.User.query.get(username='test-admin')


def setup_trove_categories():
    create_trove_categories = CreateTroveCategoriesCommand('create_trove_categories')
    with mock.patch.object(M.project.TroveCategoryMapperExtension, 'after_insert'),\
         mock.patch.object(M.project.TroveCategoryMapperExtension, 'after_update'),\
         mock.patch.object(M.project.TroveCategoryMapperExtension, 'after_delete'):
        create_trove_categories.run([''])


class TestController(object):

    application_under_test = 'main'
    validate_skip = False

    def setUp(self):
        """Method called by nose before running each test"""
        pkg = self.__module__.split('.')[0]
        self.app = ValidatingTestApp(
            setup_functional_test(app_name=self.application_under_test, current_pkg=pkg))
        self.app.extra_environ = {str('REMOTE_ADDR'): str('127.0.0.1')}  # remote_addr needed by AntiSpam
        if self.validate_skip:
            self.app.validate_skip = self.validate_skip
        if asbool(tg.config.get('smtp.mock')):
            self.smtp_mock = mock.patch('allura.lib.mail_util.smtplib.SMTP')
            self.smtp_mock.start()

    def tearDown(self):
        """Method called by nose after running each test"""
        if asbool(tg.config.get('smtp.mock')):
            self.smtp_mock.stop()

    def webflash(self, response):
        "Extract webflash content from current state of WebTest app"
        return six.moves.urllib.parse.unquote(self.app.cookies.get('webflash', ''))

    def subscription_options(self, response):
        """
        Extract subscription options to be passed to React SubscriptionForm
        component from the <script> tag
        """
        script = None
        for s in response.html.findAll('script'):
            if s.getText().strip().startswith('document.SUBSCRIPTION_OPTIONS'):
                script = s
                break
        assert script is not None, 'subscription options not found'
        _, json_dict = script.getText().split('=')
        json_dict = json_dict.strip(' ;\n')
        return json.loads(json_dict)

    def find_form(self, resp, cond):
        """Find form on the page that meets given condition"""
        for f in six.itervalues(resp.forms):
            if cond(f):
                return f


class TestRestApiBase(TestController):

    def setUp(self):
        super(TestRestApiBase, self).setUp()
        self._use_token = None
        self._token_cache = {}

    def set_api_token(self, token):
        self._use_token = token

    def token(self, username):
        if self._use_token:
            return self._use_token

        # only create token once, else ming gets dupe key error
        if username not in self._token_cache:
            user = M.User.query.get(username=username)
            consumer_token = M.OAuthConsumerToken(
                name='test-%s' % str(user._id),
                description='test-app-%s' % str(user._id),
                user_id=user._id)
            request_token = M.OAuthRequestToken(
                consumer_token_id=consumer_token._id,
                user_id=user._id,
                callback='manual',
                validation_pin=h.nonce(20))
            token = M.OAuthAccessToken(
                consumer_token_id=consumer_token._id,
                request_token_id=request_token._id,
                user_id=user._id,
                is_bearer=True)
            ming.orm.session(consumer_token).flush()
            ming.orm.session(request_token).flush()
            ming.orm.session(token).flush()
            self._token_cache[username] = token

        return self._token_cache[username]

    def _api_call(self, method, path, wrap_args=None, user='test-admin', status=None, **params):
        '''
        If you need to use one of the method kwargs as a URL parameter,
        pass params={...} as a dict instead of **kwargs
        '''
        if 'params' in params:
            params = params['params']
        if wrap_args:
            params = {wrap_args: params}
        if status is None:
            status = [200, 201, 301, 302]
        if not isinstance(params, six.string_types):
            params = variabledecode.variable_encode(params, add_repetitions=False)

        token = self.token(user).api_key
        headers = {
            'Authorization': str('Bearer {}'.format(token))
        }

        fn = getattr(self.app, method.lower())

        response = fn(
            str(path),
            params=params,
            headers=headers,
            status=status)
        if response.status_int in [301, 302]:
            return response.follow()
        else:
            return response

    def api_get(self, path, wrap_args=None, user='test-admin', status=None, **params):
        return self._api_call('GET', path, wrap_args, user, status, **params)

    def api_post(self, path, wrap_args=None, user='test-admin', status=None, **params):
        return self._api_call('POST', path, wrap_args, user, status, **params)

    def api_delete(self, path, wrap_args=None, user='test-admin', status=None, **params):
        return self._api_call('DELETE', path, wrap_args, user, status, **params)
