package main

import (
	"encoding/json"
	"os"
	"path/filepath"
	"testing"
)

func mustWrite(t *testing.T, p string, b []byte) {
	t.Helper()
	if e := os.MkdirAll(filepath.Dir(p), 0755); e != nil {
		t.Fatal(e)
	}
	if e := os.WriteFile(p, b, 0644); e != nil {
		t.Fatal(e)
	}
}
func TestJSONC(t *testing.T) {
	b := []byte("{ //x\n \"a\":1, /*z*/ \"b\":[2,],}\n")
	v, e := parseJSONBytes(b)
	if e != nil {
		t.Fatal(e)
	}
	if v["a"] == nil {
		t.Fatal("missing")
	}
}
func TestSafeJoinTraversal(t *testing.T) {
	if _, e := safeJoin(t.TempDir(), "../x"); e == nil {
		t.Fatal("traversal accepted")
	}
}
func TestPatchInventoryPreservesOther(t *testing.T) {
	target := map[string]any{"children": []any{map[string]any{"type": "X", "name": "OtherMod"}}}
	source := map[string]any{"children": []any{map[string]any{"type": "ButtonWidget", "name": "fake_stash_button", "fields": map[string]any{"rect": map[string]any{"x": 260}}}}}
	if e := patchInventory(target, source, false); e != nil {
		t.Fatal(e)
	}
	a := objChildren(target)
	if len(a) != 2 || childName(a[0]) != "OtherMod" || childName(a[1]) != "fake_stash_button" {
		t.Fatalf("preservation failed: %#v", a)
	}
}
func TestPatchWorldBankIdempotent(t *testing.T) {
	src := map[string]any{"dependencies": map[string]any{"json": []any{map[string]any{"path": prefabLogical}}}, "entities": []any{map[string]any{"type": "Entity", "name": "stash_interaction_radius", "id": json.Number("1601100001"), "components": []any{map[string]any{"prefab": prefabLogical}}}}}
	tgt := map[string]any{"dependencies": map[string]any{"json": []any{map[string]any{"path": "data/other.json"}}}, "entities": []any{map[string]any{"name": "OtherMod", "id": json.Number("9")}}}
	if e := patchWorldBank(tgt, src); e != nil {
		t.Fatal(e)
	}
	if e := patchWorldBank(tgt, src); e != nil {
		t.Fatal(e)
	}
	j := tgt["dependencies"].(map[string]any)["json"].([]any)
	if len(j) != 2 {
		t.Fatalf("dependency duplicate: %d", len(j))
	}
	es := tgt["entities"].([]any)
	if len(es) != 2 {
		t.Fatalf("entity duplicate: %d", len(es))
	}
}
func TestResolveFirstInstall(t *testing.T) {
	d, mode, e := ResolveTarget(t.TempDir(), true)
	if e != nil || mode != "mod" || filepath.Base(d) != "data" {
		t.Fatalf("%s %s %v", d, mode, e)
	}
}

func TestResolveTargetLevels(t *testing.T) {
	root := t.TempDir()
	mod := filepath.Join(root, "Sample")
	mpq := filepath.Join(mod, "Sample.mpq")
	data := filepath.Join(mpq, "data")
	os.MkdirAll(data, 0755)
	for _, sel := range []string{mod, mpq, data} {
		got, mode, e := ResolveTarget(sel, false)
		if e != nil || mode != "mod" || !samePath(got, data) {
			t.Fatalf("resolve %s => %s %s %v", sel, got, mode, e)
		}
	}
}
func TestResolveMultipleMpqFails(t *testing.T) {
	root := t.TempDir()
	os.MkdirAll(filepath.Join(root, "a.mpq", "data"), 0755)
	os.MkdirAll(filepath.Join(root, "b.mpq", "data"), 0755)
	if _, _, e := ResolveTarget(root, false); e == nil {
		t.Fatal("multiple mpq was accepted")
	}
}
