#!/usr/bin/env bash
# beagle-init — scaffold a new Beagle project.
#
# Usage:
#   beagle-init [--target TARGET] [DIRECTORY]
#
# Options:
#   --target T     Default target for the scaffold; `beagle langs` lists them
#                  all (default: clj)
#   DIRECTORY      Project directory (default: current directory)

set -euo pipefail

# Target → #lang/extension comes from the generated projection of
# beagle-lib/private/targets.rkt, so `--target` accepts exactly the targets the
# compiler has. Regenerate the projection with `beagle doc-fill`.
source "$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/share/targets.sh"

# --- Parse args ---
TARGET="clj"
DIR="."

while [[ $# -gt 0 ]]; do
    case "$1" in
        --target) TARGET="$2"; shift 2 ;;
        -*)       echo "unknown option: $1" >&2; exit 1 ;;
        *)        DIR="$1"; shift ;;
    esac
done

# --- Resolve beagle install (before cd) ---
BEAGLE_PATH="${BEAGLE_PATH:-}"
if [[ -z "$BEAGLE_PATH" ]]; then
    SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
    if [[ -f "$SCRIPT_DIR/bin/beagle-syntax" ]]; then
        BEAGLE_PATH="$SCRIPT_DIR"
    fi
fi

mkdir -p "$DIR"
cd "$DIR"

# --- Target → lang/extension (derived; never hand-listed) ---
if ! beagle_known_target "$TARGET"; then
    echo "unknown target: $TARGET (expected $BEAGLE_TARGET_IDS_LIST)" >&2
    exit 1
fi
# NOT `LANG` — that is the exported locale variable, and assigning it here
# would leak a bogus locale into every subprocess this script runs.
BEAGLE_LANG="${BEAGLE_TARGET_LANG[$TARGET]}"
EXT="${BEAGLE_TARGET_SRC_EXT[$TARGET]}"

# --- Detect an already-initialized project ---
# Never drop starter files into a populated repository.
SCAFFOLD_PROJECT=true
if [[ -f "AGENTS.md" || -d ".git" \
      || -f "package.json" || -f "flake.nix" || -f "deno.json" ]] \
   || compgen -G "src/*.b*" >/dev/null 2>&1 \
   || compgen -G "*.b*"     >/dev/null 2>&1; then
    SCAFFOLD_PROJECT=false
fi

# --- Write example source (new projects only) ---
if [[ "$SCAFFOLD_PROJECT" == true && ! -f "src/main.$EXT" ]]; then
    mkdir -p src
    cat > "src/main.$EXT" << SRCEOF
#lang $BEAGLE_LANG
(ns main)

(defn greeting [] -> String "hello from beagle")
SRCEOF
    echo "  created src/main.$EXT"
fi

# --- Write AGENTS.md (new projects only) ---
if [[ "$SCAFFOLD_PROJECT" == true && ! -f "AGENTS.md" ]]; then
    cat > AGENTS.md << 'AEOF'
# Project — beagle

This project uses **beagle**, a typed language that compiles to multiple targets.

After an edit, run `beagle syntax FILE` before `beagle check --agent FILE`.
Fix syntax before types and use the compiler's pointed repair; never count
delimiters by hand.

## Tools

- `beagle-check SOURCE` — type check a file
- `beagle-build SOURCE` — compile to target
- `beagle-expand SOURCE` — show macro expansion
- `beagle-sig NAME FILE...` — typed signature lookup
- `beagle-fields RECORD FILE...` — record field types
- `beagle-syntax --repair --write FILE` — auto-fix delimiter errors

For the form set, types, and stdlib: read `parse.rkt` and the
`stdlib-*.rkt` files in the beagle source; for the target list, run
`beagle langs`. There is no static reference document — it would go
stale within a day.
AEOF
    echo "  created AGENTS.md"
fi

# --- Hooks ---

# --- Write flake.nix (new projects only; follows beagle's nixpkgs) ---
if [[ "$SCAFFOLD_PROJECT" == true && ! -f "flake.nix" && -n "$BEAGLE_PATH" ]]; then
    cat > flake.nix << FEOF
{
  inputs = {
    beagle.url = "path:${BEAGLE_PATH}";
    nixpkgs.follows = "beagle/nixpkgs";
  };

  outputs = { nixpkgs, beagle, ... }:
    let
      system = "x86_64-linux";
      pkgs = import nixpkgs { inherit system; };
    in {
      devShells.\${system}.default = pkgs.mkShell {
        packages = with pkgs; [ racket ];
      };
    };
}
FEOF
    echo "  created flake.nix (follows beagle/nixpkgs)"
fi

# --- Write .envrc (new projects only) ---
if [[ "$SCAFFOLD_PROJECT" == true && ! -f ".envrc" && -f "flake.nix" ]]; then
    echo "use flake" > .envrc
    echo "  created .envrc"
fi

echo ""
if [[ "$SCAFFOLD_PROJECT" == true ]]; then
    echo "beagle project initialized (target: $TARGET)"
else
    echo "existing project detected — left source/config untouched"
fi
