import json
import jsonschema
import pytest

DEFAULT_REQUEST_HEADERS = {
    "Content-type": "application/json",
    "Accept": ["application/json"]
}


def test_trap_metadata(client_with_mocked_data):
    response_schema = {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "type": "object"
    }
    rv = client_with_mocked_data.get(
        '/classifier/trap-metadata/mx1.ams.nl.geant.net/ae15.1500',
        headers=DEFAULT_REQUEST_HEADERS)
    assert rv.status_code == 200
    assert rv.is_json
    response_data = json.loads(rv.data.decode('utf-8'))
    jsonschema.validate(response_data, response_schema)


@pytest.mark.parametrize("peer_address,peer_type", [
    ('109.105.110.54', 'vpn-rr-peer-info'),
    ('2001:07f8:001c:024a:0000:0000:316e:0001', 'ix-public-peer-info'),
    ('2001:07f8:000b:0100:01d1:a5d1:0310:0029', 'ix-public-peer-info'),
    ('195.66.224.238', 'ix-public-peer-info'),
]
)
def test_peer_info(client_with_mocked_data, peer_address, peer_type):
    response_schema = {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "type": "object",

        "definitions": {
            "ip-address": {
                "type": "string",
                "oneOf": [
                    {"pattern": r'^(\d+\.){3}\d+$'},
                    {"pattern": r'^([a-f\d]{4}:){7}[a-f\d]{4}$'}
                ]
            },
            "vpn-rr-peer": {
                "type": "object",
                "properties": {
                    "name": {"$ref": "#/definitions/ip-address"},
                    "description": {"type": "string"},
                    "peer-as": {"type": "integer"},
                    "router": {"type": "string"}
                },
                "required": ["name", "description"],
                "additionalProperties": False
            },

            "ix-public-peer": {
                "type": "object",
                "properties": {
                    "name": {"$ref": "#/definitions/ip-address"},
                    "description": {"type": "string"},
                    "router": {"type": "string"},
                    "as": {
                        "type": "object",
                        "properties": {
                            "local": {"type": "integer"},
                            "peer": {"type": "integer"},
                        },
                        "required": ["local", "peer"],
                        "additionalProperties": False
                    }
                },
                "required": ["name", "description", "as"],
                "additionalProperties": False
            }
        },

        "type": "object",
        "properties": {
            "ix-public-peer-info": {"$ref": "#/definitions/ix-public-peer"},
            "vpn-rr-peer-info": {"$ref": "#/definitions/vpn-rr-peer"}
        },
        "additionalProperties": False
    }

    rv = client_with_mocked_data.get(
        '/classifier/peer-info/%s' % peer_address,
        headers=DEFAULT_REQUEST_HEADERS)
    assert rv.status_code == 200
    assert rv.is_json
    response_data = json.loads(rv.data.decode('utf-8'))
    jsonschema.validate(response_data, response_schema)

    assert len(response_data) == 1, \
        "peer should be only vpn-rr or ix-public, not both"

    assert peer_type in response_data


def test_peer_not_found(client_with_mocked_data):

    rv = client_with_mocked_data.get(
        '/classifier/peer-info/1.2.3.4.5',
        headers=DEFAULT_REQUEST_HEADERS)
    assert rv.status_code == 404