package main

import (
	"fmt"
	"os"
	"path/filepath"
	"strings"

	appErrors "github.com/nexuscrm/backend/pkg/errors"
)

// generateProtectedRecords emits a runtime-queryable map of tables whose rows
// are platform-managed. The generic delete path consults this map to block
// deletion of rows where the GuardField is truthy.
//
// Output: shared/pkg/constants/z_generated_protected.go
func generateProtectedRecords(ctx *genContext, projectRoot string) error {
	var sb strings.Builder

	sb.WriteString("// Code generated by cmd/codegen. DO NOT EDIT.\n")
	sb.WriteString("// Source: internal/bootstrap/system_tables.json\n")
	sb.WriteString("// Generated at: " + ctx.timestamp + "\n\n")
	sb.WriteString("package constants\n\n")

	sb.WriteString("// ProtectedRecordSpec declares that rows whose GuardField is truthy are\n")
	sb.WriteString("// platform-managed and must be rejected by the generic delete guard.\n")
	sb.WriteString("// See backend/internal/bootstrap/system_tables.json `protectedRecords`.\n")
	sb.WriteString("type ProtectedRecordSpec struct {\n")
	sb.WriteString("\tGuardField string\n")
	sb.WriteString("\tPolicy     string\n")
	sb.WriteString("\tErrorCode  string\n")
	sb.WriteString("\tMessage    string\n")
	sb.WriteString("}\n\n")

	sb.WriteString("// ProtectedRecords maps tableName -> spec. Empty = unprotected.\n")
	sb.WriteString("var ProtectedRecords = map[string]ProtectedRecordSpec{\n")

	for _, t := range ctx.tables {
		if t.ProtectedRecords == nil {
			continue
		}
		spec := t.ProtectedRecords
		errorCode := spec.ErrorCode
		if errorCode == "" {
			errorCode = "CANNOT_DELETE_PROTECTED_RECORD"
		}
		message := spec.Message
		if message == "" {
			message = fmt.Sprintf("%s is a platform-managed record", t.TableName)
		}
		sb.WriteString(fmt.Sprintf("\t%q: {\n", t.TableName))
		sb.WriteString(fmt.Sprintf("\t\tGuardField: %q,\n", spec.GuardField))
		sb.WriteString(fmt.Sprintf("\t\tPolicy:     %q,\n", spec.Policy))
		sb.WriteString(fmt.Sprintf("\t\tErrorCode:  %q,\n", errorCode))
		sb.WriteString(fmt.Sprintf("\t\tMessage:    %q,\n", message))
		sb.WriteString("\t},\n")
	}

	sb.WriteString("}\n")

	outPath := filepath.Join(projectRoot, "shared", "pkg", "constants", "z_generated_protected.go")
	if err := os.WriteFile(outPath, []byte(sb.String()), 0644); err != nil {
		return appErrors.NewInternalError("write z_generated_protected.go", err)
	}
	fmt.Printf("✅ Generated: %s (%d bytes)\n", outPath, sb.Len())
	return nil
}
