import json

import pytest

from django.test.client import Client as DjangoClient

from oauthost.models import AuthorizationCode, Token, Client, RedirectionEndpoint, Scope
from oauthost.toolbox import register_client
from oauthost.exceptions import OauthostException


URL_TOKEN = '/token/'
URL_AUTHORIZE = '/auth/'


class OAuthostClient(DjangoClient):

    def post(self, path, data=None, **extra):
        response = super(OAuthostClient, self).post(path, data=data, **extra)
        if path == URL_TOKEN:
            response.content_json = json.loads(response.content.decode('utf-8'))
        return response


def parse_location_header(response, use_uri_fragment=False):
    delimiter = '?'
    if use_uri_fragment:
        delimiter = '#'
    query = response['Location'].split(delimiter)[1]
    query = query.split('&')
    parsed = {}
    for part in query:
        key, value = part.split('=')
        parsed[key] = value
    return parsed


@pytest.fixture
def client():
    return OAuthostClient()


class TestToolbox:

    def test_register_client(self, user):
        scope1 = Scope(identifier='scope1')
        scope1.save()

        cl = register_client('client1_title', 'client1', 'http://client1url.com/client1/', user)
        assert cl.identifier == 'client1'
        assert cl.title == 'client1_title'
        assert cl.user == user

        uris = cl.redirection_uris.all()
        assert len(uris) == 1
        assert uris[0].uri == 'http://client1url.com/client1/'

        with pytest.raises(OauthostException):
            register_client(
                'client2_title', 'client2', 'http://client2url.com/client2/', user,
                scopes_list=[scope1, 'scope2'],
                register_unknown_scopes=False)

        cl = register_client(
            'client2_title', 'client2', 'http://client2url.com/client2/', user,
             scopes_list=[scope1, 'scope2'], token_lifetime=300, public=False,
             client_params={'description': 'client2_decr'})

        assert cl.identifier == 'client2'
        assert cl.title == 'client2_title'
        assert cl.token_lifetime == 300