import boto3
import pytest

from botocore.exceptions import ClientError
from moto import mock_apigateway


@mock_apigateway
def test_put_gateway_response_minimal():
    client = boto3.client("apigateway", region_name="us-east-2")
    api_id = client.create_rest_api(name="my_api", description="d")["id"]

    resp = client.put_gateway_response(restApiId=api_id, responseType="DEFAULT_4XX")

    resp.should.have.key("responseType").equals("DEFAULT_4XX")
    resp.should.have.key("defaultResponse").equals(False)


@mock_apigateway
def test_put_gateway_response():
    client = boto3.client("apigateway", region_name="us-east-2")
    api_id = client.create_rest_api(name="my_api", description="d")["id"]

    resp = client.put_gateway_response(
        restApiId=api_id,
        responseType="DEFAULT_4XX",
        statusCode="401",
        responseParameters={"gatewayresponse.header.Authorization": "'Basic'"},
        responseTemplates={
            "application/xml": "#set($inputRoot = $input.path('$'))\n{ }"
        },
    )

    resp.should.have.key("responseType").equals("DEFAULT_4XX")
    resp.should.have.key("defaultResponse").equals(False)
    resp.should.have.key("statusCode").equals("401")
    resp.should.have.key("responseParameters").equals(
        {"gatewayresponse.header.Authorization": "'Basic'"}
    )
    resp.should.have.key("responseTemplates").equals(
        {"application/xml": "#set($inputRoot = $input.path('$'))\n{ }"}
    )


@mock_apigateway
def test_get_gateway_response_minimal():
    client = boto3.client("apigateway", region_name="ap-southeast-1")
    api_id = client.create_rest_api(name="my_api", description="d")["id"]

    client.put_gateway_response(restApiId=api_id, responseType="DEFAULT_4XX")

    resp = client.get_gateway_response(restApiId=api_id, responseType="DEFAULT_4XX")

    resp.should.have.key("responseType").equals("DEFAULT_4XX")
    resp.should.have.key("defaultResponse").equals(False)


@mock_apigateway
def test_get_gateway_response():
    client = boto3.client("apigateway", region_name="us-east-2")
    api_id = client.create_rest_api(name="my_api", description="d")["id"]

    client.put_gateway_response(
        restApiId=api_id,
        responseType="DEFAULT_4XX",
        statusCode="401",
        responseParameters={"gatewayresponse.header.Authorization": "'Basic'"},
        responseTemplates={
            "application/xml": "#set($inputRoot = $input.path('$'))\n{ }"
        },
    )

    resp = client.get_gateway_response(restApiId=api_id, responseType="DEFAULT_4XX")

    resp.should.have.key("responseType").equals("DEFAULT_4XX")
    resp.should.have.key("defaultResponse").equals(False)
    resp.should.have.key("statusCode").equals("401")
    resp.should.have.key("responseParameters").equals(
        {"gatewayresponse.header.Authorization": "'Basic'"}
    )
    resp.should.have.key("responseTemplates").equals(
        {"application/xml": "#set($inputRoot = $input.path('$'))\n{ }"}
    )


@mock_apigateway
def test_get_gateway_response_unknown():
    client = boto3.client("apigateway", region_name="us-east-2")
    api_id = client.create_rest_api(name="my_api", description="d")["id"]

    with pytest.raises(ClientError) as exc:
        client.get_gateway_response(restApiId=api_id, responseType="DEFAULT_4XX")
    err = exc.value.response["Error"]
    err["Code"].should.equal("NotFoundException")


@mock_apigateway
def test_get_gateway_responses_empty():
    client = boto3.client("apigateway", region_name="ap-southeast-1")
    api_id = client.create_rest_api(name="my_api", description="d")["id"]
    resp = client.get_gateway_responses(restApiId=api_id)

    resp.should.have.key("items").equals([])


@mock_apigateway
def test_get_gateway_responses():
    client = boto3.client("apigateway", region_name="ap-southeast-1")
    api_id = client.create_rest_api(name="my_api", description="d")["id"]
    client.put_gateway_response(restApiId=api_id, responseType="DEFAULT_4XX")
    client.put_gateway_response(
        restApiId=api_id, responseType="DEFAULT_5XX", statusCode="503"
    )

    resp = client.get_gateway_responses(restApiId=api_id)
    resp.should.have.key("items").length_of(2)

    resp["items"].should.contain(
        {"responseType": "DEFAULT_4XX", "defaultResponse": False}
    )
    resp["items"].should.contain(
        {"responseType": "DEFAULT_5XX", "defaultResponse": False, "statusCode": "503"}
    )


@mock_apigateway
def test_delete_gateway_response():
    client = boto3.client("apigateway", region_name="ap-southeast-1")
    api_id = client.create_rest_api(name="my_api", description="d")["id"]
    client.put_gateway_response(restApiId=api_id, responseType="DEFAULT_4XX")
    client.put_gateway_response(
        restApiId=api_id, responseType="DEFAULT_5XX", statusCode="503"
    )

    resp = client.get_gateway_responses(restApiId=api_id)
    resp.should.have.key("items").length_of(2)

    resp = client.delete_gateway_response(restApiId=api_id, responseType="DEFAULT_5XX")

    resp = client.get_gateway_responses(restApiId=api_id)
    resp.should.have.key("items").length_of(1)
    resp["items"].should.contain(
        {"responseType": "DEFAULT_4XX", "defaultResponse": False}
    )