package db_test

// Architecture test (#2344): db is a leaf — DB pool + migrations + raw
// SQL helpers, no business-logic dependencies. The DB layer must be
// testable with sqlmock in isolation. If db starts importing handlers
// or provisioner, every db unit test would need to bring up that
// subsystem, and the layering becomes circular.
//
// If this test fails: you put business logic in the db package. Move
// it to a higher-tier package that imports db, not the reverse.

import (
	"go/parser"
	"go/token"
	"os"
	"path/filepath"
	"strings"
	"testing"
)

const moduleInternalPrefix = "github.com/Molecule-AI/molecule-monorepo/platform/internal/"

func TestDBHasNoInternalDependencies(t *testing.T) {
	t.Parallel()
	for path, file := range listImports(t, ".") {
		if strings.HasPrefix(path, moduleInternalPrefix) {
			t.Errorf(
				"db must not import other internal packages "+
					"(found %q in %s) — db is the foundation layer and a "+
					"reverse dep creates a cycle (everything imports db). "+
					"See workspace-server/internal/db/architecture_test.go.",
				path, file,
			)
		}
	}
}

func listImports(t *testing.T, dir string) map[string]string {
	t.Helper()
	fset := token.NewFileSet()
	entries, err := os.ReadDir(dir)
	if err != nil {
		t.Fatalf("read %s: %v", dir, err)
	}
	out := make(map[string]string)
	for _, e := range entries {
		name := e.Name()
		if e.IsDir() || !strings.HasSuffix(name, ".go") || strings.HasSuffix(name, "_test.go") {
			continue
		}
		f, err := parser.ParseFile(fset, filepath.Join(dir, name), nil, parser.ImportsOnly)
		if err != nil {
			t.Fatalf("parse %s: %v", name, err)
		}
		for _, imp := range f.Imports {
			path := strings.Trim(imp.Path.Value, "\"")
			if _, seen := out[path]; !seen {
				out[path] = name
			}
		}
	}
	return out
}
