package bundler

import (
	"os"
	"path/filepath"
	"strings"
	"testing"
)

// TestCrossTreeJSBundle proves the bundler resolves the shared kit across the
// app/kjol tree boundary: a temp app entry imports @ui/Buttons, which pulls the
// real kjol web/kit (Buttons -> ./Icons -> @appgen/faIcons stub) and the solid
// runtime from web/runtime. If the alias plugin, merged vendor manifest, and
// multi-dir NodePaths all work, esbuild produces a non-empty bundle.
func TestCrossTreeJSBundle(t *testing.T) {
	webAbs, err := filepath.Abs(filepath.Join("..", "..", "web"))
	if err != nil {
		t.Fatal(err)
	}
	if _, err := os.Stat(filepath.Join(webAbs, "kit", "Buttons.tsx")); err != nil {
		t.Skipf("kjol web kit not present (%v)", err)
	}

	app := t.TempDir()
	gen := t.TempDir()
	out := t.TempDir()

	if err := os.MkdirAll(filepath.Join(app, "src"), 0o755); err != nil {
		t.Fatal(err)
	}
	entry := filepath.Join(app, "src", "app.ts")
	entrySrc := "import * as Buttons from \"@ui/Buttons\";\n" +
		"(globalThis as any).__kit = Buttons;\n"
	if err := os.WriteFile(entry, []byte(entrySrc), 0o644); err != nil {
		t.Fatal(err)
	}
	// Stub the app-owned generated FA registry that Icons.tsx imports via @appgen.
	if err := os.WriteFile(filepath.Join(gen, "faIcons.ts"), []byte("export const FA_ICONS = {};\n"), 0o644); err != nil {
		t.Fatal(err)
	}

	Configure(Config{AppFrontend: app, WebDir: webAbs, Output: out, GenTSDir: gen})

	if _, err := bundleJSEntry(entry, "app.test.js"); err != nil {
		t.Fatalf("cross-tree bundle failed: %v", err)
	}
	data, err := os.ReadFile(filepath.Join(out, "app.test.js"))
	if err != nil {
		t.Fatalf("no output bundle: %v", err)
	}
	if len(data) == 0 {
		t.Fatal("empty bundle")
	}
	t.Logf("cross-tree bundle produced %d bytes", len(data))
}

// TestCrossTreeCSS confirms the CSS pipeline compiles with the kit tree scanned
// for utility candidates across the boundary (WebDir set) without error, and
// that an app-side utility class makes it into the output.
func TestCrossTreeCSS(t *testing.T) {
	webAbs, err := filepath.Abs(filepath.Join("..", "..", "web"))
	if err != nil {
		t.Fatal(err)
	}
	if _, err := os.Stat(filepath.Join(webAbs, "kit")); err != nil {
		t.Skipf("kjol web kit not present (%v)", err)
	}

	app := t.TempDir()
	out := t.TempDir()
	if err := os.MkdirAll(filepath.Join(app, "css"), 0o755); err != nil {
		t.Fatal(err)
	}
	if err := os.MkdirAll(filepath.Join(app, "src"), 0o755); err != nil {
		t.Fatal(err)
	}
	if err := os.WriteFile(filepath.Join(app, "css", "style.css"), []byte("@import \"tailwindcss\";\n"), 0o644); err != nil {
		t.Fatal(err)
	}
	if err := os.WriteFile(filepath.Join(app, "src", "app.ts"), []byte("export const x = `<div class=\"p-4\"></div>`;\n"), 0o644); err != nil {
		t.Fatal(err)
	}

	Configure(Config{AppFrontend: app, WebDir: webAbs, Output: out})
	if _, err := compileCSSBundle("test", []string{"../src/**/*.ts"}, "test.css"); err != nil {
		t.Fatalf("cross-tree css compile failed: %v", err)
	}
	data, err := os.ReadFile(filepath.Join(out, "test.css"))
	if err != nil {
		t.Fatalf("no output css: %v", err)
	}
	if !strings.Contains(string(data), "padding") {
		t.Errorf("expected the app utility .p-4 to compile into the output")
	}
	t.Logf("cross-tree css produced %d bytes", len(data))
}
