from __future__ import unicode_literals

import random
import string
import six
import re


def random_password(
    password_length,
    exclude_characters,
    exclude_numbers,
    exclude_punctuation,
    exclude_uppercase,
    exclude_lowercase,
    include_space,
    require_each_included_type,
):

    password = ""
    required_characters = ""

    if not exclude_lowercase and not exclude_uppercase:
        password += string.ascii_letters
        required_characters += random.choice(
            _exclude_characters(string.ascii_lowercase, exclude_characters)
        )
        required_characters += random.choice(
            _exclude_characters(string.ascii_uppercase, exclude_characters)
        )
    elif not exclude_lowercase:
        password += string.ascii_lowercase
        required_characters += random.choice(
            _exclude_characters(string.ascii_lowercase, exclude_characters)
        )
    elif not exclude_uppercase:
        password += string.ascii_uppercase
        required_characters += random.choice(
            _exclude_characters(string.ascii_uppercase, exclude_characters)
        )
    if not exclude_numbers:
        password += string.digits
        required_characters += random.choice(
            _exclude_characters(string.digits, exclude_characters)
        )
    if not exclude_punctuation:
        password += string.punctuation
        required_characters += random.choice(
            _exclude_characters(string.punctuation, exclude_characters)
        )
    if include_space:
        password += " "
        required_characters += " "

    password = "".join(
        six.text_type(random.choice(password)) for x in range(password_length)
    )

    if require_each_included_type:
        password = _add_password_require_each_included_type(
            password, required_characters
        )

    password = _exclude_characters(password, exclude_characters)
    return password


def secret_arn(region, secret_id):
    id_string = "".join(random.choice(string.ascii_letters) for _ in range(5))
    return "arn:aws:secretsmanager:{0}:1234567890:secret:{1}-{2}".format(
        region, secret_id, id_string
    )


def _exclude_characters(password, exclude_characters):
    for c in exclude_characters:
        if c in string.punctuation:
            # Escape punctuation regex usage
            c = "\{0}".format(c)
        password = re.sub(c, "", str(password))
    return password


def _add_password_require_each_included_type(password, required_characters):
    password_with_required_char = password[: -len(required_characters)]
    password_with_required_char += required_characters

    return password_with_required_char
