# -*- coding: utf-8 -*-
# type: ignore
from __future__ import annotations

import http

from django.test import Client
from django.urls import reverse
import pytest


@pytest.fixture
def call(rpc_call_factory):
    return rpc_call_factory(
        'accounts.auth.check',
        [],
    )


@pytest.mark.django_db
def test_ok_session_auth(authenticated_client: Client,
                         call,
                         ):
    # When
    result = authenticated_client.post(
        reverse('ui.accounts.rpc'),
        data=call,
        content_type='application/json',
    )

    # Then
    assert result.status_code == http.HTTPStatus.OK

    call_result = result.json()
    assert 'error' not in call_result
    assert call_result['result'] is True


@pytest.mark.django_db
def test_session_auth_inactive_account(inactive_account_client: Client,
                                       call,
                                       ):
    # When
    result = inactive_account_client.post(
        reverse('ui.accounts.rpc'),
        data=call,
        content_type='application/json',
    )

    # Then
    assert result.status_code == http.HTTPStatus.OK

    call_result = result.json()
    assert 'error' not in call_result
    assert call_result['result'] is False


@pytest.mark.django_db
def test_ok_access_token_auth(client: Client,
                              call,
                              access_token_out,
                              ):
    # When
    result = client.post(
        reverse('ui.accounts.rpc'),
        data=call,
        content_type='application/json',
        headers={
            'Authorization': f'Bearer {access_token_out.key}',
        },
    )

    # Then
    assert result.status_code == http.HTTPStatus.OK

    call_result = result.json()
    assert 'error' not in call_result
    assert call_result['result'] is True


@pytest.mark.django_db
def test_access_token_auth_not_bearer(client: Client,
                                      call,
                                      access_token_out,
                                      ):
    # When
    result = client.post(
        reverse('ui.accounts.rpc'),
        data=call,
        content_type='application/json',
        headers={
            'Authorization': f'thisisntright {access_token_out.key}',
        },
    )

    # Then
    assert result.status_code == http.HTTPStatus.OK

    call_result = result.json()
    assert 'error' not in call_result
    assert call_result['result'] is False


@pytest.mark.django_db
def test_access_token_auth_invalid_access_token(client: Client,
                                                call,
                                                null_uuid,
                                                ):
    # When
    result = client.post(
        reverse('ui.accounts.rpc'),
        data=call,
        content_type='application/json',
        headers={
            'Authorization': f'Bearer {null_uuid}',
        },
    )

    # Then
    assert result.status_code == http.HTTPStatus.OK

    call_result = result.json()
    assert 'error' not in call_result
    assert call_result['result'] is False


@pytest.mark.django_db
def test_access_token_auth_deleted_access_token(client: Client,
                                                call,
                                                deleted_access_token,
                                                ):
    # When
    result = client.post(
        reverse('ui.accounts.rpc'),
        data=call,
        content_type='application/json',
        headers={
            'Authorization': f'Bearer {deleted_access_token.key}',
        },
    )

    # Then
    assert result.status_code == http.HTTPStatus.OK

    call_result = result.json()
    assert 'error' not in call_result
    assert call_result['result'] is False


@pytest.mark.django_db
def test_access_token_auth_inactive_account(client: Client,
                                            call,
                                            inactive_account_access_token,
                                            ):
    # When
    result = client.post(
        reverse('ui.accounts.rpc'),
        data=call,
        content_type='application/json',
        headers={
            'Authorization': f'Bearer {inactive_account_access_token.key}',
        },
    )

    # Then
    assert result.status_code == http.HTTPStatus.OK

    call_result = result.json()
    assert 'error' not in call_result
    assert call_result['result'] is False


@pytest.mark.django_db
def test_anonymous(client: Client, call):
    # When
    result = client.post(
        reverse('ui.accounts.rpc'),
        data=call,
        content_type='application/json',
    )

    # Then
    assert result.status_code == http.HTTPStatus.OK

    call_result = result.json()
    assert 'error' not in call_result
    assert call_result['result'] is False
