lib/mix/tasks/foundry.init.ex

defmodule Mix.Tasks.Foundry.Init do
  @moduledoc """
  Initialize a new Foundry project by scaffolding required directories and files.

  Usage:
    mix foundry.init [target_directory]

  If no target directory is provided, the current directory is used.
  """

  use Mix.Task

  def run(args) do
    target_dir = List.first(args) || File.cwd!()
    normalized_target = target_dir |> String.trim() |> Path.expand()

    unless File.dir?(normalized_target) do
      Mix.raise("Target directory does not exist: #{normalized_target}")
    end

    scaffold_foundry_project(normalized_target)
  end

  defp scaffold_foundry_project(target) do
    source_root = source_root()

    Mix.shell().info("[:] Scaffolding Foundry project in #{target}")

    scaffold_agents(source_root, target)
    scaffold_specify(source_root, target)
    scaffold_foundry_manifest(target)
    scaffold_docs_directories(target)
    scaffold_agents_md(source_root, target)
    scaffold_gitignore(source_root, target)

    Mix.shell().info("[:] Foundry project initialized successfully!")
  end

  defp scaffold_agents(source_root, target) do
    source_agents = Path.join(source_root, ".agents/skills")
    target_agents = Path.join(target, ".agents/skills")

    if File.exists?(source_agents) and not File.exists?(target_agents) do
      Mix.shell().info("  [:] Copying agent skills...")
      File.mkdir_p!(Path.dirname(target_agents))
      copy_recursive!(source_agents, target_agents)
    end
  end

  defp scaffold_specify(source_root, target) do
    source_specify = Path.join(source_root, ".specify")
    target_specify = Path.join(target, ".specify")

    if File.exists?(source_specify) and not File.exists?(target_specify) do
      Mix.shell().info("  [:] Copying specification templates...")
      File.mkdir_p!(target_specify)
      copy_recursive!(source_specify, target_specify)
    end
  end

  defp scaffold_foundry_manifest(target) do
    manifest_dir = Path.join(target, ".foundry")
    manifest_file = Path.join(manifest_dir, "manifest.exs")

    unless File.exists?(manifest_file) do
      Mix.shell().info("  [:] Creating foundry manifest...")
      File.mkdir_p!(manifest_dir)

      project_name = Path.basename(target)

      manifest_content = """
      # Foundry Project Manifest
      # Auto-generated: #{DateTime.utc_now()}

      %{
        name: "#{project_name}",
        description: "A Foundry project",
        version: "0.0.1",
        domains: [],
        agent_skills: ["thinking", "chat", "research"],
        integrations: []
      }
      """

      File.write!(manifest_file, manifest_content)
    end
  end

  defp scaffold_docs_directories(target) do
    dirs = ["docs/adrs", "docs/runbooks", "docs/regulations"]

    Enum.each(dirs, fn dir ->
      full_path = Path.join(target, dir)
      unless File.dir?(full_path) do
        File.mkdir_p!(full_path)
      end
    end)

    Mix.shell().info("  [:] Created documentation directories...")
  end

  defp scaffold_agents_md(source_root, target) do
    source_agents_md = Path.join(source_root, "AGENTS.md")
    target_agents_md = Path.join(target, "AGENTS.md")

    if File.exists?(source_agents_md) and not File.exists?(target_agents_md) do
      Mix.shell().info("  [:] Copying AGENTS.md...")
      File.cp!(source_agents_md, target_agents_md)
    end
  end

  defp scaffold_gitignore(source_root, target) do
    source_gitignore = Path.join(source_root, "reference_projects/igaming/.gitignore")
    target_gitignore = Path.join(target, ".gitignore")

    if File.exists?(source_gitignore) and not File.exists?(target_gitignore) do
      Mix.shell().info("  [:] Copying .gitignore...")
      File.cp!(source_gitignore, target_gitignore)
    end
  end

  defp source_root do
    # Try environment variable first
    case System.get_env("FOUNDRY_SOURCE_ROOT") do
      nil ->
        # Try application dir
        case Application.app_dir(:foundry, "priv/scaffold") do
          path when is_binary(path) and path != "" -> path
          _ -> derive_source_root()
        end

      env_root ->
        env_root
    end
  end

  defp derive_source_root do
    # Go up 5 levels from lib/mix/tasks to repo root
    __DIR__
    |> Path.split()
    |> Enum.take(length(Path.split(__DIR__)) - 5)
    |> Path.join()
  end

  defp copy_recursive!(source, target) do
    File.cp_r!(source, target)
  end
end