"""
Pytest plugin for gcplocal.

Provides fixtures that other projects can use by simply installing gcplocal.
Auto-discovered by pytest via the entry point in pyproject.toml.

Usage in any project's tests:

    def test_my_gcp_code(gcplocal_client):
        # gcplocal_client is a Flask test client pointing at the emulator
        resp = gcplocal_client.post(
            "/compute/v1/projects/my-proj/zones/us-central1-a/instances",
            json={"name": "test-vm"},
        )
        assert resp.status_code == 200

    def test_with_live_server(gcplocal_url):
        # gcplocal_url is "http://localhost:<port>" with a real server running
        import requests
        resp = requests.get(f"{gcplocal_url}/health")
        assert resp.json()["status"] == "healthy"
"""

import threading
import socket

import pytest


def _find_free_port():
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.bind(("", 0))
        return s.getsockname()[1]


@pytest.fixture(scope="session")
def _gcplocal_state():
    from gcplocal.state import StateStore
    return StateStore()


@pytest.fixture
def gcplocal_state(_gcplocal_state):
    """Fresh state store — cleared before each test."""
    _gcplocal_state.clear()
    return _gcplocal_state


@pytest.fixture
def gcplocal_app(gcplocal_state):
    """Flask application wired to a clean state store."""
    from gcplocal.server import create_app
    app = create_app(gcplocal_state)
    app.config["TESTING"] = True
    return app


@pytest.fixture
def gcplocal_client(gcplocal_app):
    """
    Flask test client for the gcplocal emulator.

    No real HTTP server is started — requests go through Flask's
    internal WSGI layer, which is fast and side-effect free.
    """
    return gcplocal_app.test_client()


@pytest.fixture(scope="session")
def gcplocal_url():
    """
    Start a real gcplocal HTTP server on a random port and return its URL.

    Useful when you need to point real GCP client libraries or
    external tools at the emulator. The server is shared across
    all tests in the session and shut down automatically.
    """
    from gcplocal.server import create_app
    from gcplocal.state import StateStore
    from werkzeug.serving import make_server

    state = StateStore()
    app = create_app(state)
    port = _find_free_port()

    server = make_server("127.0.0.1", port, app)
    thread = threading.Thread(target=server.serve_forever, daemon=True)
    thread.start()

    url = f"http://127.0.0.1:{port}"
    yield url

    server.shutdown()


@pytest.fixture
def gcplocal_terraform_env(gcplocal_url):
    """
    Returns a dict of environment-style config for pointing Terraform
    or GCP client libraries at the running gcplocal instance.
    """
    return {
        "project": "gcplocal-test",
        "url": gcplocal_url,
        "compute_custom_endpoint": f"{gcplocal_url}/compute/v1/",
        "storage_custom_endpoint": f"{gcplocal_url}/storage/v1/",
        "iam_custom_endpoint": f"{gcplocal_url}/v1/",
        "pubsub_custom_endpoint": f"{gcplocal_url}/v1/",
        "cloud_resource_manager_custom_endpoint": f"{gcplocal_url}/v1/",
        "sql_custom_endpoint": f"{gcplocal_url}/sql/v1beta4/",
        "access_token": "gcplocal-mock-token",
    }
