defmodule Symbiont.Application do
  @moduledoc """
  OTP Application for Symbiont — the self-sustaining AI orchestrator.

  Supervision tree (dev/prod):
    Symbiont.Supervisor
    ├── Task.Supervisor (Symbiont.TaskSupervisor)
    ├── Symbiont.Ledger        — append-only cost log
    ├── Symbiont.Queue         — persistent task queue
    ├── Symbiont.Engram        — cross-session memory (SQLite)
    ├── Symbiont.Heartbeat     — periodic health checks + queue processing
    └── Bandit (Symbiont.API)  — HTTP API

  In test mode, the supervisor starts empty — tests manage their own processes.
  """
  use Application

  @impl true
  def start(_type, _args) do
    if Application.get_env(:symbiont, :port) == 0 do
      # Test mode: start an empty supervisor, tests manage their own processes
      Supervisor.start_link([], strategy: :one_for_one, name: Symbiont.Supervisor)
    else
      start_full()
    end
  end

  defp start_full do
    data_dir = Application.get_env(:symbiont, :data_dir, "data")
    File.mkdir_p!(data_dir)

    port = Application.get_env(:symbiont, :port, 8111)
    engram_db = Application.get_env(:symbiont, :engram_db, "/data/symbiont/engram.db")

    children = [
      {Task.Supervisor, name: Symbiont.TaskSupervisor},
      {Symbiont.Ledger, data_dir: data_dir},
      {Symbiont.Queue, data_dir: data_dir},
      {Symbiont.Engram, db_path: engram_db},
      {Symbiont.Heartbeat, []},
      {Bandit, plug: Symbiont.API, port: port, scheme: :http}
    ]

    opts = [strategy: :rest_for_one, name: Symbiont.Supervisor]
    Supervisor.start_link(children, opts)
  end
end
