#!/usr/bin/env nu
# install/gen-remote-projects.nu — manage ~/.config/ontoref/remote-projects.ncl.
#
# Remote projects push their ontology via POST /sync — no local file watch.
# Optionally verifies git reachability when --check-git is passed.
#
# Usage:
#   nu install/gen-remote-projects.nu --add <url> <slug>     # register remote project
#   nu install/gen-remote-projects.nu --remove <slug>        # unregister remote project
#   nu install/gen-remote-projects.nu --list                 # list registered remotes
#   nu install/gen-remote-projects.nu --check-git            # probe all git remotes

def main [
  --add: string = "",     # remote URL to register (requires --slug)
  --slug: string = "",    # slug for the new remote project
  --remove: string = "",  # slug to remove
  --list,                 # list registered remote projects
  --check-git,            # probe git reachability for all entries with remote_url
  --config-dir: string = "",
] {
  let cfg_dir = if ($config_dir | is-empty) {
    $"($env.HOME)/.config/ontoref"
  } else {
    $config_dir
  }
  let remote_file   = $"($cfg_dir)/remote-projects.ncl"
  let schemas_dir   = $"($cfg_dir)/schemas"

  if not ($remote_file | path exists) {
    "[]" | save -f $remote_file
  }

  # ── List ─────────────────────────────────────────────────────────────────────
  if $list {
    let entries = (parse-entries $remote_file)
    if ($entries | is-empty) {
      print "  no remote projects registered"
    } else {
      for e in $entries {
        print $"  ($e.slug)  ($e.remote_url)"
      }
    }
    return
  }

  # ── Check git reachability ────────────────────────────────────────────────────
  if $check_git {
    let entries = (parse-entries $remote_file)
    for e in $entries {
      if ($e.remote_url | is-not-empty) {
        let r = (do { ^git ls-remote --exit-code --heads $e.remote_url } | complete)
        if $r.exit_code == 0 {
          print $"  (ansi green)reachable(ansi reset)   ($e.slug)  ($e.remote_url)"
        } else {
          print $"  (ansi yellow)unreachable(ansi reset) ($e.slug)  ($e.remote_url)"
        }
      }
    }
    return
  }

  # ── Remove ────────────────────────────────────────────────────────────────────
  if ($remove | is-not-empty) {
    let entries = (parse-entries $remote_file)
    let filtered = ($entries | where { |e| $e.slug != $remove })
    if ($filtered | length) == ($entries | length) {
      print $"  (ansi yellow)not found(ansi reset): ($remove)"
    } else {
      write-entries $filtered $remote_file $schemas_dir
      print $"  (ansi green)removed(ansi reset): ($remove)"
    }
    return
  }

  # ── Add ───────────────────────────────────────────────────────────────────────
  if ($add | is-not-empty) {
    if ($slug | is-empty) {
      error make { msg: "--add requires --slug <slug>" }
    }
    let entries = (parse-entries $remote_file)
    if ($entries | any { |e| $e.slug == $slug }) {
      error make { msg: $"slug '($slug)' already registered" }
    }
    let new_entry = { slug: $slug, remote_url: $add }
    let all = ($entries | append $new_entry)
    write-entries $all $remote_file $schemas_dir
    print $"  (ansi green)registered(ansi reset): ($slug)  ($add)"
    return
  }

  print "  nothing to do — use --add, --remove, --list, or --check-git"
}

# ── Helpers ───────────────────────────────────────────────────────────────────

# Extract { slug, remote_url } pairs from remote-projects.ncl as plain text.
def parse-entries [file: string]: nothing -> list<record<slug: string, remote_url: string>> {
  open $file
  | lines
  | each { |l| $l | str trim }
  | reduce --fold [] { |l, acc|
      let slug_match       = ($l | parse --regex 'slug\s*=\s*"(?P<v>[^"]+)"' | get v? | first?)
      let remote_url_match = ($l | parse --regex 'remote_url\s*=\s*"(?P<v>[^"]+)"' | get v? | first?)
      if ($slug_match | is-not-empty) {
        $acc | append { slug: ($slug_match | into string), remote_url: "" }
      } else if ($remote_url_match | is-not-empty) and ($acc | is-not-empty) {
        let last = ($acc | last)
        ($acc | drop 1) | append { slug: $last.slug, remote_url: ($remote_url_match | into string) }
      } else {
        $acc
      }
    }
}

def write-entries [entries: list, file: string, schemas_dir: string]: nothing -> nothing {
  let schema_import = $"\"($schemas_dir)/ontoref-project.ncl\""
  let blocks = (
    $entries | each { |e|
      $"  \(let s = import ($schema_import) in\n  s.make_remote_project \{\n    slug       = \"($e.slug)\",\n    remote_url = \"($e.remote_url)\",\n    keys       = [],\n  \}\),"
    }
    | str join "\n"
  )

  let output = if ($entries | is-empty) {
    "# AUTO-GENERATED by ontoref project-add-remote. Do not edit by hand.\n\n[]\n"
  } else {
    "# AUTO-GENERATED by ontoref project-add-remote. Do not edit by hand.\n\n[\n" + $blocks + "\n]\n"
  }
  $output | save -f $file
}
