"""
Utilities for testing.

:copyright: Copyright 2013-2017, Dorian Pula <dorian.pula@amber-penguin-software.ca>
:license: AGPL v3+
"""

import collections
import random
import string

import requests
from werkzeug import security

from rookeries.pages import models as page_models
from rookeries.users import models as user_models


RANDOM_SUFFIX_CHARACTERS = list(string.ascii_lowercase + string.digits)

ResponseSampleBundle = collections.namedtuple(
    'ResponseSampleBundle', ['response', 'sample'])


def generate_test_password():
    return ''.join(random.choices(string.printable, k=8))


def hash_password(password):
    return security.generate_password_hash(password)


def generate_random_suffix():
    return ''.join(random.choices(RANDOM_SUFFIX_CHARACTERS, k=10))


def generate_test_user(db, user_prefix='test'):
    """
    Creates a new test user.

    :param user_prefix: The prefix for the username of the test user.
    :return: A tuple with information about the test user.
    """

    username = f'{user_prefix}-{generate_random_suffix()}'
    email = f'{username}@test.rookeries.org'
    password = generate_test_password()
    user = user_models.User(
        username=username,
        password=password,
        # TODO: Come up with better random names for tests
        fullName=f'{generate_random_suffix()} {generate_random_suffix()}',
        profile={
            'email': email
        }
    )
    db.create_document(doc=user.to_db_json())
    user_in_db = user_models.User(
        **db.find_first_document({
            'type': user_models.User.doc_type(),
            'username': username,
        })
    )

    return user_in_db, password


def generate_test_page(db, slug='', title='', content=''):
    test_page_slug = slug if slug else f'test-{generate_random_suffix()}'

    # TODO: Should check if page exists first.

    test_page_ = page_models.Page(
        slug=test_page_slug,
        title=title,
        content=content
    )

    db.create_document(doc=test_page_.to_db_json())
    return page_models.Page(
        **db.find_first_document({
            'type': page_models.Page.doc_type(),
            'slug': test_page_slug,
        })
    )


def extract_response(response):
    if isinstance(response, requests.Response):
        return response
    return response.response
