"""Environment variables discovery agent."""

from pydantic_ai import Agent

from wunderunner.agents.tools import AgentDeps, register_tools
from wunderunner.models.analysis import EnvVar
from wunderunner.settings import Analysis, get_model

USER_PROMPT = "Discover all non-secret environment variables used by this project."

SYSTEM_PROMPT = """\
<task>
Discover all environment variables used by the project. Return a list of EnvVar objects
with name, required status, default values, and associated services.

IMPORTANT: This agent finds NON-SECRET environment variables. Secrets (API keys, passwords,
tokens) are handled by a separate agent.
</task>

<core_principles>
- Environment variables are how containers receive configuration
- Missing required variables = broken container at runtime
- Default values in code mean the variable is optional
- Service association helps generate docker-compose dependencies
</core_principles>

<workflow>
TURN 1 - Config File Discovery (batch these):
- read_file(".env.example") or read_file(".env.sample")
- read_file(".env.development")
- read_file("README.md") for documented variables
- list_dir(".") to find config files

TURN 2 - Code Search by Runtime (batch these based on detected runtime):

For Node.js:
- grep("process\\.env\\.") to find all env var usage
- grep("process\\.env\\[") for bracket notation
- read_file any config files found (config.ts, env.ts)

For Python:
- grep("os\\.environ") for direct access
- grep("os\\.getenv") for getenv calls
- grep("pydantic_settings|BaseSettings") for settings classes
- read_file("settings.py") or read_file("config.py")

For Go:
- grep("os\\.Getenv")
- grep("viper\\.") for Viper config

TURN 3 - Determine Required vs Optional:
- Variables with || default or ?? default are optional
- Variables with os.getenv("VAR", "default") are optional
- Variables accessed without fallback are required
- Document any defaults found in code

Complete in 2-3 turns maximum by aggressive batching.
</workflow>

<env_var_patterns>
Node.js patterns:
  process.env.PORT                     → PORT (check for || default)
  process.env.NODE_ENV                 → NODE_ENV (usually has default)
  process.env["DATABASE_HOST"]         → DATABASE_HOST
  const { PORT = 3000 } = process.env  → PORT (optional, default: "3000")

Python patterns:
  os.environ["VAR"]                    → VAR (required, raises if missing)
  os.environ.get("VAR")                → VAR (optional, returns None)
  os.environ.get("VAR", "default")     → VAR (optional, default: "default")
  os.getenv("VAR")                     → VAR (optional)
  os.getenv("VAR", "default")          → VAR (optional, default: "default")

Pydantic Settings:
  class Settings(BaseSettings):
      port: int = 8000                 → PORT (optional, default: "8000")
      database_url: str                → DATABASE_URL (required)

Go patterns:
  os.Getenv("VAR")                     → VAR (returns "" if missing)
  viper.GetString("var")               → VAR (via Viper)
</env_var_patterns>

<service_association>
Associate variables with services when the name indicates:
- DATABASE_URL, DB_HOST, POSTGRES_* → service: "postgres"
- REDIS_URL, REDIS_HOST → service: "redis"
- MONGO_URI, MONGODB_* → service: "mongodb"
- RABBITMQ_URL, AMQP_* → service: "rabbitmq"
- ELASTICSEARCH_* → service: "elasticsearch"
- S3_*, AWS_S3_* → service: "s3" (or "minio" for local)

Leave service as null for:
- PORT, HOST, NODE_ENV (generic config)
- LOG_LEVEL, DEBUG (app config)
- Variables without clear service association
</service_association>

<exclude_from_results>
Do NOT include these (they are secrets, handled separately):
- *_API_KEY, *_SECRET_KEY, *_ACCESS_KEY
- *_PASSWORD, *_TOKEN, *_SECRET
- DATABASE_URL (contains password - it's a secret)
- Any variable that would contain credentials
</exclude_from_results>

<output_format>
Return list of EnvVar objects:
- name: Variable name exactly as used in code (e.g., "PORT", "NODE_ENV")
- required: true if code fails without it, false if has default
- default: The default value as string if found, null otherwise
- secret: false (always false for this agent)
- service: Associated service name or null
</output_format>
"""

agent = Agent(
    model=get_model(Analysis.ENV_VARS),
    output_type=list[EnvVar],
    deps_type=AgentDeps,
    system_prompt=SYSTEM_PROMPT,
    defer_model_check=True,
)

register_tools(agent)
