package mysql

import (
	"context"
	"database/sql"
)

// ensureResourceEntitlementSnapshotSchema upgrades pre-snapshot wallets without rewriting legacy mutable
// entitlements. Empty hash/id is the explicit legacy semantic; pinned grants always write all three fields.
func ensureResourceEntitlementSnapshotSchema(ctx context.Context, db *sql.DB) error {
	var database string
	if err := db.QueryRowContext(ctx, `SELECT DATABASE()`).Scan(&database); err != nil {
		return err
	}
	columns := []struct {
		name string
		ddl  string
	}{
		{name: "source_snapshot_id", ddl: `ALTER TABLE user_resource_entitlements ADD COLUMN source_snapshot_id VARCHAR(96) NOT NULL DEFAULT '' AFTER source_grant_id`},
		{name: "resource_snapshot_hash", ddl: `ALTER TABLE user_resource_entitlements ADD COLUMN resource_snapshot_hash CHAR(64) NOT NULL DEFAULT '' AFTER source_snapshot_id`},
		{name: "resource_snapshot_json", ddl: `ALTER TABLE user_resource_entitlements ADD COLUMN resource_snapshot_json JSON NULL AFTER resource_snapshot_hash`},
		{name: "gift_snapshot_hash", ddl: `ALTER TABLE user_resource_entitlements ADD COLUMN gift_snapshot_hash CHAR(64) NOT NULL DEFAULT '' AFTER resource_snapshot_json`},
		{name: "gift_snapshot_json", ddl: `ALTER TABLE user_resource_entitlements ADD COLUMN gift_snapshot_json JSON NULL AFTER gift_snapshot_hash`},
	}
	for _, column := range columns {
		var count int
		if err := db.QueryRowContext(ctx, `
			SELECT COUNT(*) FROM information_schema.COLUMNS
			WHERE TABLE_SCHEMA = ? AND TABLE_NAME = 'user_resource_entitlements' AND COLUMN_NAME = ?`, database, column.name).Scan(&count); err != nil {
			return err
		}
		if count == 0 {
			if _, err := db.ExecContext(ctx, column.ddl); err != nil {
				return err
			}
		}
	}
	var indexCount int
	if err := db.QueryRowContext(ctx, `
		SELECT COUNT(*) FROM information_schema.STATISTICS
		WHERE TABLE_SCHEMA = ? AND TABLE_NAME = 'user_resource_entitlements' AND INDEX_NAME = 'idx_user_resource_semantic'`, database).Scan(&indexCount); err != nil {
		return err
	}
	if indexCount == 0 {
		_, err := db.ExecContext(ctx, `
			CREATE INDEX idx_user_resource_semantic
			ON user_resource_entitlements (app_code, user_id, resource_id, resource_snapshot_hash, status, expires_at_ms)`)
		return err
	}
	return nil
}
