"""
Utilities for testing.

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

import collections
import random
import string

import requests
from faker import Faker

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'])
faker_generator = Faker()


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


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


def generate_test_user(db, username='', password=''):
    """
    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 = faker_generator.user_name() if not username else username
    password = generate_test_password() if not password else password
    user = user_models.User(
        username=username,
        password=password,
        fullName=faker_generator.name(),
        profile={
            'email': faker_generator.safe_email()
        }
    )
    db.create_or_update_document(doc=user.to_db_json())
    user_in_db = user_models.User.find_in_db(db, {'username': username})
    return user_in_db, password


def generate_test_page(db, slug='', title='', content='') -> page_models.Page:
    def fake_page():
        page_content = [f'# {faker_generator.sentence()}', '']
        for _ in range(0, 4):
            # TODO: Make fake content more compelling?
            page_content.append(faker_generator.text())

        return '\n'.join(page_content)

    test_page_slug = slug if slug else faker_generator.slug()
    test_page_title = title if title else faker_generator.sentence()
    test_content = content if content else fake_page()

    # TODO: Should check if page exists first.

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

    db.create_or_update_document(doc=test_page_.to_db_json())
    return page_models.Page.find_in_db(db, {'slug': test_page_slug})


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