"""Stub adapter — no real API calls.  Used in local dev / CI when CF credentials are absent.

Implements both the routing plane and deployment plane interfaces so the stub can replace
either provider without code changes in tasks.
"""
from __future__ import annotations

import structlog

from src.config import Settings, get_settings
from src.domain.hosting.hostnames import canonical_live_url, canonical_preview_url
from src.domain.hosting.types import (
    DeployArtifact,
    DeployJobContext,
    DeploymentOutcome,
    DeploymentTarget,
    RoutingDescriptor,
)

logger = structlog.get_logger()


class StubHostingProvider:
    """No-op provider for both routing and deployment planes."""

    def __init__(self, settings: Settings | None = None):
        self._s = settings or get_settings()

    def _canonical_url(self, ctx: DeployJobContext) -> str:
        apex = self._s.hosting_public_apex or "sites.p2hs.com"
        if (ctx.environment or "").lower() == "preview":
            return canonical_preview_url(ctx.project_ref, apex)
        return canonical_live_url(ctx.project_ref, apex)

    # ------------------------------------------------------------------
    # Deployment plane
    # ------------------------------------------------------------------
    async def ensure_project_environment(self, ctx: DeployJobContext) -> DeploymentOutcome:
        logger.info("stub_ensure", project_ref=ctx.project_ref, env=ctx.environment)
        return DeploymentOutcome(
            ok=True,
            deploy_url=self._canonical_url(ctx),
            last_completed_step="ensure_project_environment",
            metadata={"adapter": "stub"},
        )

    async def deploy_artifact(
        self,
        ctx: DeployJobContext,
        artifact: DeployArtifact,
        target: DeploymentTarget,
    ) -> DeploymentOutcome:
        logger.info("stub_deploy", project_ref=ctx.project_ref, sha=artifact.source_git_sha[:12])
        return DeploymentOutcome(
            ok=True,
            deploy_url=self._canonical_url(ctx),
            activation_status="stub_ok",
            last_completed_step="deploy_artifact",
            metadata={"adapter": "stub"},
        )

    async def activate_deployment(self, ctx: DeployJobContext) -> DeploymentOutcome:
        return DeploymentOutcome(
            ok=True,
            deploy_url=self._canonical_url(ctx),
            activation_status="live",
            last_completed_step="activate_deployment",
            metadata={"adapter": "stub"},
        )

    async def get_deployment_status(self, ctx: DeployJobContext) -> DeploymentOutcome:
        return DeploymentOutcome(
            ok=True,
            deploy_url=self._canonical_url(ctx),
            activation_status="stub_ok",
            last_completed_step="get_deployment_status",
            metadata={"adapter": "stub"},
        )

    # ------------------------------------------------------------------
    # Routing plane
    # ------------------------------------------------------------------
    async def ensure_dispatch_namespace(self, environment: str) -> dict:
        return {"namespace_name": f"stub-{environment}"}

    async def upsert_route(self, hostname: str, descriptor: RoutingDescriptor, environment: str) -> None:
        logger.info("stub_upsert_route", hostname=hostname, target=descriptor.target_url)

    async def delete_route(self, hostname: str, project_ref: str, environment: str) -> None:
        logger.info("stub_delete_route", hostname=hostname)

    async def activate_route(
        self,
        ctx: DeployJobContext,
        target_url: str,
        deployment_target_id: str | None = None,
        active_deployment_id: str | None = None,
    ) -> DeploymentOutcome:
        return DeploymentOutcome(
            ok=True,
            deploy_url=self._canonical_url(ctx),
            activation_status="live",
            last_completed_step="activate_route",
            metadata={"adapter": "stub"},
        )

    # ------------------------------------------------------------------
    # CF Pages polling stub
    # ------------------------------------------------------------------
    async def ensure_pages_project(self, project_ref: str, repo_full_name: str, project_type: str, preview_branch: str = "preview") -> dict:
        return {"name": f"stub-{project_ref}", "repo_linkage_status": "stub"}

    async def find_deployment_for_sha(self, project_ref: str, commit_sha: str, branch: str):
        # Stub: pretend the deployment is immediately live
        return {
            "id": f"stub-{commit_sha[:8]}",
            "url": f"https://stub-{project_ref}.pages.dev",
            "latest_stage": {"name": "deploy", "status": "success"},
            "stages": [{"name": "deploy", "status": "success"}],
            "deployment_trigger": {"type": "push", "metadata": {"branch": branch, "commit_hash": commit_sha}},
        }

    async def is_deployment_live(self, deployment: dict) -> bool:
        return True

    async def is_deployment_failed(self, deployment: dict) -> bool:
        return False


# Legacy name alias
StubWorkersForPlatformsProvider = StubHostingProvider
