// Source of go_pgmetrics_vectors.json, generated against platform-pgcommon's legacy-removal
// cutover (Tier 1 only; RegistryEntry has no Supersedes/SupersededBy/Sunset), on top of 17d0faf.
// Kept as .txt so nothing here compiles it. To regenerate: copy into an empty directory as
// main.go with a go.mod that `replace`s github.com/BCBP-SOLUTIONS-FZC-LLC/platform-pgcommon
// with a local checkout, then `GOWORK=off go mod tidy && go run . > go_pgmetrics_vectors.json`.
//
// Throwaway generator for platform-pgcommon-py's tests/fixtures/go_pgmetrics_vectors.json:
// the Tier 1 entries of Go's real pgmetrics.Registry() and the operation label Go's real
// SQL-verb extractor (via OTelQueryTracer's db.operation.name) assigns to each SQL vector.
package main

import (
	"context"
	"encoding/json"
	"os"

	"github.com/BCBP-SOLUTIONS-FZC-LLC/platform-pgcommon/pkg/pgmetrics"
	"github.com/jackc/pgx/v5"
	sdktrace "go.opentelemetry.io/otel/sdk/trace"
	"go.opentelemetry.io/otel/sdk/trace/tracetest"
)

type entry struct {
	Name               string              `json:"name"`
	Type               string              `json:"type"`
	Tier               string              `json:"tier"`
	Status             string              `json:"status"`
	SemanticDefinition string              `json:"semantic_definition"`
	RequiredLabels     []string            `json:"required_labels"`
	ApprovedLabels     []string            `json:"approved_labels"`
	LabelValues        map[string][]string `json:"label_values"`
	LabelValueRules    map[string]string   `json:"label_value_rules"`
	Cardinality        string              `json:"cardinality"`
	AggregationNotes   string              `json:"aggregation_notes"`
	GovernanceNotes    string              `json:"governance_notes"`
}

var sqls = []string{
	"SELECT * FROM orders", "  insert into orders values (1)", "UPDATE orders SET x = 1",
	"delete from orders", "WITH cte AS (SELECT 1) SELECT * FROM cte", "VACUUM ANALYZE orders",
	"", "   ", "select(1)", "SELECT;", "\tmerge into t using s on true", "/* app=svc */ SELECT 1",
	"/* a */ /* b */\n-- c\nINSERT INTO t VALUES (1)", "-- only a comment", "/* unterminated SELECT 1",
	"SELECTX 1", "\fSELECT 1", " SELECT 1", "start transaction", "refresh materialized view v",
	"DISCARD ALL", "drop table x", "BEGIN", "COMMIT", "ROLLBACK TO SAVEPOINT sp", "SAVEPOINT sp",
	"RELEASE SAVEPOINT sp", "SELECT set_config('app.user_id', $1, false)", "COPY t FROM STDIN",
	"values (1)", "table t", "call p()", "do $$ begin end $$", "comment on table t is 'x'",
	"lock table t", "listen ch", "notify ch", "unlisten *", "show all", "reset all", "set x = 1",
	"explain select 1", "analyze t", "prepare p as select 1", "end", "grant select on t to r",
	"revoke select on t from r", "truncate t", "alter table t add c int", "create table t()",
	"\r\n\tSELECT\n1", "--x\r\nSELECT 1", "/**/SELECT 1", "/* nested /* */ SELECT 1", "SeLeCt 1",
	"FETCH 10 FROM c", "CLOSE ALL", "DECLARE c CURSOR FOR SELECT 1", "SELECT 1", "(SELECT 1)",
	"ſelect 1",
}

func main() {
	var out struct {
		Registry        []entry           `json:"registry"`
		OperationValues []string          `json:"operation_values"`
		Operations      map[string]string `json:"operations"`
	}
	for _, e := range pgmetrics.Registry() {
		if e.Status != pgmetrics.StatusProposed {
			continue
		}
		out.Registry = append(out.Registry, entry{
			Name: e.Name, Type: string(e.Type), Tier: string(e.Tier), Status: string(e.Status),
			SemanticDefinition: e.SemanticDefinition, RequiredLabels: e.RequiredLabels, ApprovedLabels: e.ApprovedLabels,
			LabelValues: e.LabelValues, LabelValueRules: e.LabelValueRules, Cardinality: e.Cardinality,
			AggregationNotes: e.AggregationNotes, GovernanceNotes: e.GovernanceNotes,
		})
		if e.Name == "platform_db_queries_total" {
			out.OperationValues = e.LabelValues["operation"]
		}
	}
	rec := tracetest.NewSpanRecorder()
	tp := sdktrace.NewTracerProvider(sdktrace.WithSpanProcessor(rec))
	qt := pgmetrics.NewOTelQueryTracer(tp.Tracer("dump"))
	out.Operations = map[string]string{}
	for _, sql := range sqls {
		ctx := qt.TraceQueryStart(context.Background(), nil, pgx.TraceQueryStartData{SQL: sql})
		qt.TraceQueryEnd(ctx, nil, pgx.TraceQueryEndData{})
		spans := rec.Ended()
		for _, kv := range spans[len(spans)-1].Attributes() {
			if kv.Key == "db.operation.name" {
				out.Operations[sql] = kv.Value.AsString()
			}
		}
	}
	enc := json.NewEncoder(os.Stdout)
	enc.SetIndent("", "  ")
	enc.SetEscapeHTML(false)
	_ = enc.Encode(out)
}
