# ━━━ miao (庙) — the temple of versions ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# A version control system in the Ling language, its lexicon drawn from
# ling 灵 — the numinous — in Chinese religion. A repository is a temple;
# every file version is a spirit, enshrined by whichever rite fits it.
#
# Run from source:    ling run --interp ling/main.ling <command> …
# Or use the launcher: miao.bat / ./miao.sh
#
# Every command answers to three names: english · pinyin · git.

use "util.ling"
use "colors.ling"
use "store.ling"
use "diffy.ling"
use "rites.ling"
use "remote.ling"
use "gui.ling"

# extract user args: everything after the entry .ling file (or argv[1..])
fn mx_args() {
    bind a = get_args()
    bind from = 1.0
    bind i = 0.0
    while i < len(a) {
        if str_ends_with(list_get(a, i), ".ling") {
            bind from = i + 1.0
            bind i = len(a)
        }
        bind i = i + 1.0
    }
    bind out = list_new()
    bind i = from
    while i < len(a) {
        bind out = list_push(out, list_get(a, i))
        bind i = i + 1.0
    }
    return out
}

fn mx_canon(c) {
    if c == "consecrate" || c == "kai" || c == "init" { return "consecrate" }
    if c == "divine" || c == "wen" || c == "status" || c == "st" { return "divine" }
    if c == "offer" || c == "gong" || c == "add" || c == "stage" { return "offer" }
    if c == "withdraw" || c == "che" || c == "unstage" { return "withdraw" }
    if c == "rite" || c == "ji" || c == "commit" || c == "ci" { return "rite" }
    if c == "lineage" || c == "pu" || c == "log" { return "lineage" }
    if c == "yinyang" || c == "diff" || c == "yy" { return "yinyang" }
    if c == "soul" || c == "hun" || c == "branch" || c == "br" { return "soul" }
    if c == "summon" || c == "zhao" || c == "switch" || c == "checkout" || c == "co" { return "summon" }
    if c == "harmonize" || c == "he" || c == "merge" { return "harmonize" }
    if c == "talisman" || c == "fu" || c == "tag" { return "talisman" }
    if c == "manifest" || c == "xian" || c == "show" || c == "cat" { return "manifest" }
    if c == "enshrine" || c == "fenling" || c == "clone" { return "enshrine" }
    if c == "mother" || c == "zumiao" || c == "remote" { return "mother" }
    if c == "pilgrimage" || c == "jinxiang" || c == "pull" || c == "fetch" { return "pilgrimage" }
    if c == "tribute" || c == "huixiang" || c == "push" { return "tribute" }
    if c == "fair" || c == "hui" || c == "serve" || c == "share" { return "fair" }
    if c == "restore" || c == "huan" { return "restore" }
    if c == "keeper" || c == "config" { return "keeper" }
    if c == "vessel" || c == "bundle" { return "vessel" }
    if c == "chronicle" || c == "reflog" { return "chronicle" }
    if c == "gui" { return "gui" }
    if c == "help" || c == "qiu" || c == "--help" || c == "-h" { return "help" }
    if c == "version" || c == "--version" || c == "-v" { return "version" }
    return c
}

fn mx_help_row(en, zh, git, what) {
    print("  " + cx_good(ut_pad(en, 22.0)) + cx_tal(ut_pad(zh, 12.0)) + cx_meta(ut_pad(git, 10.0)) + cx_dim(what))
    return 0.0
}

fn mx_help() {
    cx_banner()
    print(cx_dim("  a repository is a temple; every file version is a spirit."))
    print(cx_dim("  every command answers to three names: ") + cx_good("english") + cx_dim(" · ") + cx_tal("pinyin") + cx_dim(" · ") + cx_meta("git"))
    print("")
    mx_help_row("consecrate [dir]", "kai 开光", "init", "found a temple here")
    mx_help_row("divine", "wen 问", "status", "ask the oracle what has changed")
    mx_help_row("offer <paths|.>", "gong 供", "add", "place spirits on the altar")
    mx_help_row("withdraw <paths>", "che 撤", "unstage", "take an offering back")
    mx_help_row("rite -m \"...\"", "ji 祭", "commit", "seal the altar into history")
    mx_help_row("lineage [-n N|--all]", "pu 谱", "log", "read the genealogy of rites")
    mx_help_row("yinyang [a] [b]", "阴阳", "diff", "dark removed · light added")
    mx_help_row("soul [name|-d name]", "hun 魂", "branch", "the temple's many souls")
    mx_help_row("summon <soul|rite>", "zhao 召", "switch", "call a soul into the worktree")
    mx_help_row("harmonize <soul>", "he 合", "merge", "bring two souls into harmony")
    mx_help_row("talisman [name]", "fu 符", "tag", "fix a name to a moment")
    mx_help_row("manifest [rite|path]", "xian 显", "show", "let a spirit manifest")
    mx_help_row("restore <paths>", "huan 还", "restore", "return a file to its enshrined form")
    print("")
    print(cx_dim("  — the incense network ") + cx_tal("分香") + cx_dim(" —"))
    mx_help_row("fair [--tribute]", "hui 庙会", "serve", "open your temple over SSH (share link)")
    mx_help_row("enshrine <link>", "fenling 分灵", "clone", "found a daughter temple from a link")
    mx_help_row("enshrine near", "", "", "discover fairs on your LAN")
    mx_help_row("mother [add n l]", "zumiao 祖庙", "remote", "the ancestral temples you follow")
    mx_help_row("pilgrimage [m]", "jinxiang 进香", "pull", "fetch + fast-forward from the mother")
    mx_help_row("tribute [m]", "huixiang 回香", "push", "carry your rites up (needs a tribute link)")
    mx_help_row("vessel <file>", "法器", "bundle", "seal the temple into one portable file")
    print("")
    mx_help_row("keeper [name]", "守庙人", "config", "who signs your rites")
    mx_help_row("chronicle", "编年", "reflog", "everything the temple remembers doing")
    mx_help_row("gui", "", "", "open the LingMiao window (LSX-themed)")
    print("")
    print(cx_dim("  storage is adaptive: ") + cx_good("○ whole") + cx_dim(" · ") + cx_info("◐ delta chain") + cx_dim(" · ") + cx_tal("◍ content-defined chunks") + cx_dim(" — chosen per spirit, per rite"))
    print(cx_dim("  flags: --plain (no color) · MIAO_PLAIN=1"))
    return 0.0
}

fn mx_need_temple() {
    if sx_root() != "" { return true }
    print(cx_err("no temple stands here — ") + cx_dim("`miao consecrate` to found one, or `miao enshrine <link>` to clone"))
    return false
}

fn mx_consecrate(args) {
    bind where = "."
    if len(args) > 0.5 { bind where = list_get(args, 0.0) }
    bind abs = ut_norm(absolute_path(where))
    if where != "." { make_dir(abs) }
    bind r = sx_init(abs)
    if r == "exists" {
        print(cx_warn("a temple already stands at " + abs))
        return 0.0
    }
    st_set("sx_root", abs)
    cx_banner()
    print(cx_good("✦ the ground is consecrated — a temple stands at"))
    print("  " + cx_info(abs))
    print("")
    print(cx_dim("  the living soul is ") + cx_info("main") + cx_dim(". begin:"))
    print(cx_dim("    ") + cx_stage("miao offer .") + cx_dim("            place every spirit on the altar"))
    print(cx_dim("    ") + cx_stage("miao rite -m \"genesis\"") + cx_dim("  seal the first rite"))
    sx_log("consecrate", abs)
    return 0.0
}

fn mx_rite(args) {
    bind msg = ""
    bind i = 0.0
    while i < len(args) {
        bind a0 = list_get(args, i)
        if a0 == "-m" || a0 == "--message" {
            bind msg = list_get(args, i + 1.0)
            bind i = i + 1.0
        } else if msg == "" {
            bind msg = a0
        }
        bind i = i + 1.0
    }
    rt_rite(msg)
    return 0.0
}

fn mx_lineage(args) {
    bind limit = 20.0
    bind all_flag = false
    bind i = 0.0
    while i < len(args) {
        bind a0 = list_get(args, i)
        if a0 == "-n" {
            bind limit = to_number(list_get(args, i + 1.0))
            bind i = i + 1.0
        }
        if a0 == "--all" { bind all_flag = true }
        bind i = i + 1.0
    }
    rt_lineage(limit, all_flag)
    return 0.0
}

fn mx_keeper(args) {
    if len(args) < 1.0 {
        print(cx_meta("keeper of this temple: ") + cx_good(sx_author()))
        print(cx_dim("  (set with `miao keeper \"Your Name\"`)"))
        return 0.0
    }
    bind name = list_join(args, " ")
    sx_cfg_set("author", name)
    print(cx_good("✦ the temple now knows its keeper: ") + cx_info(name))
    return 0.0
}

fn mx_chronicle() {
    bind lines = ut_read_lines(sx_dir() + "/chronicle")
    if len(lines) < 1.0 {
        print(cx_dim("the chronicle is blank"))
        return 0.0
    }
    bind i = len(lines) - 1.0
    bind shown = 0.0
    while i >= 0.0 && shown < 30.0 {
        bind parts = split(list_get(lines, i), "|")
        bind t = to_number(list_get(parts, 0.0))
        print(cx_meta(ut_fmt_time(t)) + "  " + cx_info(ut_pad(list_get(parts, 1.0), 14.0)) + cx_dim(list_get(parts, 2.0)))
        bind i = i - 1.0
        bind shown = shown + 1.0
    }
    return 0.0
}

bind start = do {
    bind raw = mx_args()
    # global flags
    bind plain = 0.0
    if env_get("MIAO_PLAIN", "") != "" { bind plain = 1.0 }
    bind args = list_new()
    bind i = 0.0
    while i < len(raw) {
        bind a0 = list_get(raw, i)
        if a0 == "--plain" {
            bind plain = 1.0
        } else {
            bind args = list_push(args, a0)
        }
        bind i = i + 1.0
    }
    cx_init(plain)
    bind cmd = ""
    if len(args) > 0.5 { bind cmd = mx_canon(list_get(args, 0.0)) }
    bind rest = list_new()
    bind i = 1.0
    while i < len(args) {
        bind rest = list_push(rest, list_get(args, i))
        bind i = i + 1.0
    }
    if cmd == "" || cmd == "help" {
        mx_help()
    } else if cmd == "version" {
        print(cx_rainbow("miao") + cx_dim(" 1.0.0 — the temple of versions, in Ling"))
    } else if cmd == "consecrate" {
        mx_consecrate(rest)
    } else if cmd == "enshrine" {
        nx_enshrine(rest)
    } else if cmd == "gui" {
        gx_main(rest)
    } else if mx_need_temple() == false {
        bind done = 1.0
    } else if cmd == "divine" {
        rt_divine()
    } else if cmd == "offer" {
        rt_offer(rest)
    } else if cmd == "withdraw" {
        rt_withdraw(rest)
    } else if cmd == "rite" {
        mx_rite(rest)
    } else if cmd == "lineage" {
        mx_lineage(rest)
    } else if cmd == "yinyang" {
        rt_yinyang(rest)
    } else if cmd == "soul" {
        rt_soul(rest)
    } else if cmd == "summon" {
        rt_summon(rest)
    } else if cmd == "harmonize" {
        rt_harmonize(rest)
    } else if cmd == "talisman" {
        rt_talisman(rest)
    } else if cmd == "manifest" {
        rt_manifest(rest)
    } else if cmd == "restore" {
        rt_restore(rest)
    } else if cmd == "mother" {
        nx_mother(rest)
    } else if cmd == "pilgrimage" {
        nx_pilgrimage(rest)
    } else if cmd == "tribute" {
        nx_tribute(rest)
    } else if cmd == "fair" {
        nx_fair(rest)
    } else if cmd == "vessel" {
        nx_vessel(rest)
    } else if cmd == "keeper" {
        mx_keeper(rest)
    } else if cmd == "chronicle" {
        mx_chronicle()
    } else {
        print(cx_err("the temple knows no ceremony called \"" + cmd + "\"") + cx_dim("  — try `miao help`"))
    }
}
