import json

from bottle import request, response

import model
from util import debug


def missing_attributes(attributes):
    for attr in attributes:
        if attr not in request.json:
            if str(attr) == 'session_id':
                return 'You are not signed in.'
            return 'Missing value for attribute ' + str(attr)
        if str(attr) == 'session_id':
            if not model.valid_session_id(request.json['session_id']):
                return 'You are not signed in.'
    return False


def login():
    missing = missing_attributes(['username', 'password'])
    if missing:
        return bad_request(missing)
    username = request.json['username']
    password = request.json['password']
    session_id = model.login(username, password)
    if session_id:
        return {'session_id': session_id}
    else:
        return forbidden('Invalid login data')


def depot():
    missing = missing_attributes(['session_id'])
    if missing:
        return bad_request(missing)
    data = model.get_user_ownership(model.get_user_id_by_session_id(request.json['session_id']))
    return {'data': data}


def register():
    missing = missing_attributes(['username', 'password'])
    if missing:
        return bad_request(missing)
    username = request.json['username']
    password = request.json['password']
    if model.user_exists(username):
        return forbidden('User already exists.')
    game_key = ''
    if 'game_key' in request.json:
        game_key = request.json['game_key'].strip().upper()
        if game_key != '' and game_key not in model.unused_keys():
            return bad_request('Game key is not valid.')
    if model.register(username, password, game_key):
        return {'message': "successfully registered user"}
    else:
        return bad_request('registration not successful')


def activate_key():
    missing = missing_attributes(['key', 'session_id'])
    if missing:
        return bad_request(missing)
    if model.valid_key(request.json['key']):
        user_id = model.get_user_id_by_session_id(request.json['session_id'])
        model.activate_key(request.json['key'], user_id)
        return {'message': "successfully activated key"}
    else:
        return bad_request('Invalid key.')


def order():
    missing = missing_attributes(['buy', 'session_id', 'amount', 'ownable'])
    if missing:
        return bad_request(missing)
    if not model.ownable_name_exists(request.json['ownable']):
        return bad_request('This kind of object can not be ordered.')
    buy = request.json['buy']
    sell = not buy
    session_id = request.json['session_id']
    amount = request.json['amount']
    ownable_name = request.json['ownable']
    ownable_id = model.ownable_id_by_name(ownable_name)
    user_id = model.get_user_id_by_session_id(session_id)
    model.own(user_id, ownable_name)
    ownership_id = model.get_ownership_id(ownable_id, user_id)

    limit = None
    if 'limit' in request.json:
        limit = request.json['limit']
    stop_loss = 'stop_loss' in request.json and bool(request.json['stop_loss'])
    # TODO test if stop loss works

    if sell:
        if not model.user_owns_at_least(user_id, amount, ownership_id):
            return bad_request('You can not sell more than you own.')

    model.place_order(buy, ownership_id, limit, stop_loss, amount)
    return {'message': "Order placed."}


def orders():
    missing = missing_attributes(['session_id'])
    if missing:
        return bad_request(missing)
    data = model.get_user_orders(model.get_user_id_by_session_id(request.json['session_id']))
    return {'data': data}


def news():
    missing = missing_attributes(['session_id'])
    if missing:
        return bad_request(missing)
    return {'data': model.news()}


def transactions():
    missing = missing_attributes(['session_id', 'ownable_id'])
    if missing:
        return bad_request(missing)
    if not model.ownable_name_exists(request.json['ownable']):
        return bad_request('This kind of object can not have transactions.')
    return {'data': model.transactions()}


def not_found(msg=''):
    response.status = 404
    if debug:
        msg = str(response.status) + ': ' + msg
    response.content_type = 'application/json'
    return json.dumps({"error_message": msg})


def forbidden(msg=''):
    response.status = 403
    if debug:
        msg = str(response.status) + ' Forbidden: ' + msg
    response.content_type = 'application/json'
    return json.dumps({"error_message": msg})


def bad_request(msg=''):
    response.status = 400
    if debug:
        msg = str(response.status) + ' Bad request: ' + msg
    response.content_type = 'application/json'
    return json.dumps({"error_message": msg})