# -*- coding: utf-8 -*-

import os

import pytest

from arkindex.exceptions import ErrorResponse
from arkindex.mock import MockApiClient


def test_mock_client(responses):
    # Allow accessing remote API schemas, defaulting to the prod environment
    schema_url = os.environ.get(
        "ARKINDEX_API_SCHEMA_URL",
        "https://arkindex.teklia.com/api/v1/openapi/?format=json",
    )
    responses.add_passthru(schema_url)

    # Configure mock for dummy endpoints
    mock = MockApiClient()
    mock.add_response(
        "ListAnimals",
        [
            {
                "type": "cat",
                "name": "Henri",
            },
            {
                "type": "dog",
                "name": "Rick",
            },
        ],
    )
    invalid_body = mock.add_response(
        "CreateTag",
        name="Henri",
        body={"tag": "This is not the right payload"},
        response={
            "id": "1234-cat",
        },
    )
    mock.add_response(
        "CreateTag",
        name="Henri",
        body={"tag": "yyy"},
        response={
            "id": "1234-cat",
        },
    )
    extra_response = mock.add_response(
        "CreateTag",
        name="Nope",
        response={
            "id": "shouldNotAppear",
        },
    )
    mock.add_response(
        "CreateTag",
        name="Rick",
        body={"tag": "xxx"},
        response={
            "id": "5678-dog",
        },
    )
    mock.add_error_response(
        "DeleteTag",
        name="Henri",
        body={"tag": "yyy"},
        status_code=403,
        title="Forbidden",
        content="You cannot perform this action",
    )

    # Call the endpoints - this simulates business code
    animals = mock.paginate("ListAnimals")
    assert len(animals) == 2
    assert animals == [
        {
            "type": "cat",
            "name": "Henri",
        },
        {
            "type": "dog",
            "name": "Rick",
        },
    ]

    assert mock.request("CreateTag", name="Rick", body={"tag": "xxx"}) == {
        "id": "5678-dog",
    }
    assert mock.request("CreateTag", name="Henri", body={"tag": "yyy"}) == {
        "id": "1234-cat",
    }

    with pytest.raises(ErrorResponse) as e_info:
        mock.request("DeleteTag", name="Henri", body={"tag": "yyy"})
    error_response = e_info.value
    assert error_response.status_code == 403
    assert error_response.title == "Forbidden"
    assert error_response.content == "You cannot perform this action"

    # A request not mocked should raise an exception
    with pytest.raises(ErrorResponse):
        mock.request("DoSomething", parameter="value")

    # Check the mockup history
    assert len(mock.history) == 5
    assert [req.operation for req in mock.history] == [
        "ListAnimals",
        "CreateTag",
        "CreateTag",
        "DeleteTag",
        "DoSomething",
    ]

    # Almost all responses have been consumed
    assert len(mock.responses) == 2
    assert mock.responses == [invalid_body, extra_response]
