# global imports (dont't worry, red is normal)
from db.entities.user import User
from services.user_service import UserService
from services.login_wrapper import login_required
from services.token_service import TokenService

from flask import request, Response
import bcrypt
import jwt
import json

def secret():
    return "Pineapple does not belong to pizza!"

def verify(token):
    '''
    verifies the validity of a JWT token.
    performs the following tests (int this order):
        - is the JWT token parsable? (it has not been damaged + the signature is valid)
        - does the payload contain all necessary fields?
        - does the user specified by the payload exist?
        - is the expiration/creation date sound?
    '''

    try:
        user = TokenService.verify("Bearer "+token)

        return Response(status = 200, response=json.dumps(user.to_serializable_dict()))
    except ValueError as e:
        return Response(status=401, response=str(e))    

def authenticate():
    '''
    takes the credentials from the user and generates a JWT token out of them
    '''
    data = request.json
    username = data["username"]

    try:
        user = UserService.get_by_credentials(username, data["password"])

        TokenService.successful_authentication(user)

        return {"token": TokenService.generate_token(user)}
    except ValueError as e:
        # return 400 if the user does not exist or the password is wrong
        return Response(status = 400, response=str(e))

def delete(username):
    '''
    deletes a user from the DB. should be protected later
    '''
    try:
        UserService.delete(username)

        return Response(status = 200)
    except ValueError as e:
        # return 400 if the user already exists
        return Response(status = 400, response=str(e))

def add():
    '''
    adds a new user to the DB. expects the provided password to be plaintext i.e. it should not
    be encrypted, encoded or hashed
    '''
    data = request.json

    # overwrite possibly existing role with "regular user"
    data["role"] = "u"
    
    username = data["username"]

    try :
        UserService.add(username, data["password"], data["role"])
    except ValueError as e:
        # return 400 if the user already exists
        return Response(status = 400, response=str(e))

    return Response(status=200)

def all():
    '''
    return all users stored in the DB
    '''

    users = UserService._repository.all()

    return str(users)