from datasette.app import Datasette
from datasette_endpoints import _simplify_pattern
import pytest


@pytest.mark.asyncio
async def test_plugin_is_installed():
    datasette = Datasette(memory=True)
    response = await datasette.client.get("/-/plugins.json")
    assert response.status_code == 200
    installed_plugins = {p["name"] for p in response.json()}
    assert "datasette-endpoints" in installed_plugins


@pytest.mark.asyncio
async def test_endpoints_json():
    datasette = Datasette(memory=True)
    response = await datasette.client.get("/-/endpoints.json")
    assert response.status_code == 200
    assert "application/json" in response.headers.get("content-type", "")
    data = response.json()
    assert isinstance(data, list)
    # Each endpoint should have path, view, and pattern keys
    for endpoint in data:
        assert "path" in endpoint
        assert "view" in endpoint
        assert "pattern" in endpoint


@pytest.mark.asyncio
async def test_endpoints_json_contains_known_routes():
    datasette = Datasette(memory=True)
    response = await datasette.client.get("/-/endpoints.json")
    data = response.json()
    paths = [e["path"] for e in data]
    # Should contain well-known Datasette endpoints
    assert "/-/plugins" in paths
    assert "/-/settings" in paths
    assert "/-/versions" in paths
    assert "/-/databases" in paths
    # Should contain itself
    assert "/-/endpoints" in paths


@pytest.mark.asyncio
async def test_endpoints_json_includes_plugin_routes():
    # The endpoints plugin itself registers a route, which should show up
    datasette = Datasette(memory=True)
    response = await datasette.client.get("/-/endpoints.json")
    data = response.json()
    paths = [e["path"] for e in data]
    assert "/-/endpoints" in paths
    assert "/-/endpoints.json" in paths


@pytest.mark.asyncio
async def test_endpoints_json_view_names():
    datasette = Datasette(memory=True)
    response = await datasette.client.get("/-/endpoints.json")
    data = response.json()
    by_path = {e["path"]: e for e in data}
    # Plugin views should show their function names
    assert by_path["/-/endpoints.json"]["view"] == "endpoints_json"
    assert by_path["/-/endpoints"]["view"] == "endpoints_html"


@pytest.mark.asyncio
async def test_endpoints_json_database_routes():
    datasette = Datasette(memory=True)
    response = await datasette.client.get("/-/endpoints.json")
    data = response.json()
    paths = [e["path"] for e in data]
    assert "/{database}" in paths
    assert "/{database}.db" in paths


@pytest.mark.asyncio
async def test_endpoints_html():
    datasette = Datasette(memory=True)
    response = await datasette.client.get("/-/endpoints")
    assert response.status_code == 200
    assert "text/html" in response.headers.get("content-type", "")
    # Should contain some known endpoint paths
    assert "/-/plugins" in response.text
    assert "/-/settings" in response.text


@pytest.mark.asyncio
async def test_endpoints_html_extends_base():
    datasette = Datasette(memory=True)
    response = await datasette.client.get("/-/endpoints")
    # Should use Datasette's base template - check for standard layout elements
    assert "app.css" in response.text
    assert "<footer" in response.text


@pytest.mark.asyncio
async def test_endpoints_html_title():
    datasette = Datasette(memory=True)
    response = await datasette.client.get("/-/endpoints")
    assert "<title>Endpoints</title>" in response.text


@pytest.mark.asyncio
async def test_endpoints_html_structure():
    datasette = Datasette(memory=True)
    response = await datasette.client.get("/-/endpoints")
    assert "<table>" in response.text
    assert "<th>Path</th>" in response.text
    assert "<th>View</th>" in response.text
    assert "<th>Pattern</th>" in response.text


def test_simplify_pattern_basic():
    assert _simplify_pattern("^/-/plugins$") == "/-/plugins"


def test_simplify_pattern_with_format():
    assert _simplify_pattern(r"^/-/plugins(\.(?P<format>json))?$") == "/-/plugins"


def test_simplify_pattern_named_groups():
    assert _simplify_pattern(r"^/(?P<database>[^\/\.]+)\.db$") == "/{database}.db"


def test_simplify_pattern_multiple_groups():
    result = _simplify_pattern(
        r"^/(?P<database>[^\/\.]+)/(?P<table>[^\/\.]+)(\.(?P<format>\w+))?$"
    )
    assert result == "/{database}/{table}"


def test_simplify_pattern_root():
    result = _simplify_pattern(r"^/(\.(?P<format>jsono?))?$")
    assert result == "/"
