# -*- coding: utf-8 -*-
"""
    flask_security.script
    ~~~~~~~~~~~~~~~~~~~~~

    Flask-Security script module

    :copyright: (c) 2012 by Matt Wright.
    :license: MIT, see LICENSE for more details.
"""
from __future__ import print_function

import re
import warnings

from flask import current_app
from flask_script import Command, Option
from werkzeug.local import LocalProxy

from .utils import hash_password

try:
    import simplejson as json
except ImportError:
    import json

warnings.warn(
    "Please use flask_security.cli instead of flask_security.script. "
    "Support for Flask-Script will be removed in 2.1.",
    DeprecationWarning,
)

_datastore = LocalProxy(lambda: current_app.extensions["security"].datastore)


def pprint(obj):
    print(json.dumps(obj, sort_keys=True, indent=4))


def commit(fn):
    def wrapper(*args, **kwargs):
        fn(*args, **kwargs)
        _datastore.commit()

    return wrapper


class CreateUserCommand(Command):
    """Create a user"""

    option_list = (
        Option("-e", "--email", dest="email", default=None),
        Option("-p", "--password", dest="password", default=None),
        Option("-a", "--active", dest="active", default=""),
    )

    @commit
    def run(self, **kwargs):
        # sanitize active input
        ai = re.sub(r"\s", "", str(kwargs["active"]))
        kwargs["active"] = ai.lower() in ["", "y", "yes", "1", "active"]

        from flask_security.forms import ConfirmRegisterForm
        from werkzeug.datastructures import MultiDict

        form = ConfirmRegisterForm(MultiDict(kwargs), meta={"csrf": False})

        if form.validate():
            kwargs["password"] = hash_password(kwargs["password"])
            _datastore.create_user(**kwargs)
            print("User created successfully.")
            kwargs["password"] = "****"
            pprint(kwargs)
        else:
            print("Error creating user")
            pprint(form.errors)


class CreateRoleCommand(Command):
    """Create a role"""

    option_list = (
        Option("-n", "--name", dest="name", default=None),
        Option("-d", "--desc", dest="description", default=None),
    )

    @commit
    def run(self, **kwargs):
        _datastore.create_role(**kwargs)
        print('Role "%(name)s" created successfully.' % kwargs)


class _RoleCommand(Command):
    option_list = (
        Option("-u", "--user", dest="user_identifier"),
        Option("-r", "--role", dest="role_name"),
    )


class AddRoleCommand(_RoleCommand):
    """Add a role to a user"""

    @commit
    def run(self, user_identifier, role_name):
        _datastore.add_role_to_user(user_identifier, role_name)
        print(
            "Role '%s' added to user '%s' successfully" % (role_name, user_identifier)
        )


class RemoveRoleCommand(_RoleCommand):
    """Remove a role from a user"""

    @commit
    def run(self, user_identifier, role_name):
        _datastore.remove_role_from_user(user_identifier, role_name)
        print(
            "Role '%s' removed from user '%s' successfully"
            % (role_name, user_identifier)
        )


class _ToggleActiveCommand(Command):
    option_list = (Option("-u", "--user", dest="user_identifier"),)


class DeactivateUserCommand(_ToggleActiveCommand):
    """Deactivate a user"""

    @commit
    def run(self, user_identifier):
        _datastore.deactivate_user(user_identifier)
        print("User '%s' has been deactivated" % user_identifier)


class ActivateUserCommand(_ToggleActiveCommand):
    """Activate a user"""

    @commit
    def run(self, user_identifier):
        _datastore.activate_user(user_identifier)
        print("User '%s' has been activated" % user_identifier)
