// Copyright 2026 printing-press-golden and contributors. Licensed under Apache-2.0. See LICENSE.
// Generated by CLI Printing Press (https://github.com/mvanhorn/cli-printing-press). DO NOT EDIT.

package lookups

import (
	"database/sql"
	"errors"
	"fmt"
)

// SeedConfig is the canonical-+-values shape supplied by the consumer
// CLI's spec (LearnConfig.EntityLookupSeeds). Use SeedFromConfig to
// materialize one or many of these into the entity_lookups table on
// first start (or on every start; INSERT OR IGNORE is idempotent).
//
// Why a map keyed by kind: it matches the spec shape directly and
// keeps the per-CLI seeding wiring trivial. The runtime LookupRow
// shape is denormalized at insert time.
type SeedConfig struct {
	Canonical string
	Values    []string
}

// SeedFromConfig walks the supplied per-kind seed map and inserts
// every (kind, canonical, alias, "seeded") row via SeedBatch. Returns
// the number of rows actually inserted (i.e., not skipped by the
// idempotency check).
//
// The whole batch runs inside a single transaction so a partial seed
// can't leave the DB in a state where some kinds are populated and
// others aren't. db must be non-nil; an empty map is a no-op and
// returns (0, nil).
//
// This is the canonical seeding entrypoint when the consumer CLI
// derives its seed data from the spec at print time (the generator
// stamps the per-CLI seed map and a call to SeedFromConfig at first
// start). Hand-built per-CLI seeders should call SeedBatch directly.
func SeedFromConfig(db *sql.DB, seedsByKind map[string][]SeedConfig) (int, error) {
	if db == nil {
		return 0, errors.New("lookups.SeedFromConfig: db is nil")
	}
	if len(seedsByKind) == 0 {
		return 0, nil
	}
	tx, err := db.Begin()
	if err != nil {
		return 0, fmt.Errorf("lookups.SeedFromConfig begin: %w", err)
	}
	defer tx.Rollback()

	rows := make([]LookupRow, 0)
	for kind, seeds := range seedsByKind {
		for _, s := range seeds {
			// The canonical itself counts as a value of itself so a
			// query that types the canonical name resolves back. The
			// PRIMARY KEY constraint protects against duplicates if the
			// spec author also lists the canonical in Values.
			rows = append(rows, LookupRow{
				Kind:      kind,
				Canonical: s.Canonical,
				Value:     s.Canonical,
				Source:    "seeded",
			})
			for _, value := range s.Values {
				rows = append(rows, LookupRow{
					Kind:      kind,
					Canonical: s.Canonical,
					Value:     value,
					Source:    "seeded",
				})
			}
		}
	}
	inserted, err := SeedBatch(tx, rows)
	if err != nil {
		return inserted, err
	}
	if err := tx.Commit(); err != nil {
		return inserted, fmt.Errorf("lookups.SeedFromConfig commit: %w", err)
	}
	return inserted, nil
}
