package mysql

import (
	"fmt"
	"reflect"

	"gorm.io/gorm"
)

// schemaCache memoizes table/column existence checks for a single DB handle.
// It is intended for startup-time feature detection, not per-request probing.
type schemaCache struct {
	db           *gorm.DB
	tableExists  map[string]bool
	columnExists map[string]bool
}

func newSchemaCache(db *gorm.DB) *schemaCache {
	return &schemaCache{
		db:           db,
		tableExists:  make(map[string]bool),
		columnExists: make(map[string]bool),
	}
}

func (s *schemaCache) HasTable(dst any) bool {
	key := schemaKey(dst)
	if ok, found := s.tableExists[key]; found {
		return ok
	}
	ok := s.db.Migrator().HasTable(dst)
	s.tableExists[key] = ok
	return ok
}

func (s *schemaCache) HasColumn(dst any, column string) bool {
	key := schemaKey(dst) + "\x00" + column
	if ok, found := s.columnExists[key]; found {
		return ok
	}
	ok := s.db.Migrator().HasColumn(dst, column)
	s.columnExists[key] = ok
	return ok
}

func schemaKey(dst any) string {
	if dst == nil {
		return "<nil>"
	}
	if s, ok := dst.(string); ok {
		return "table:" + s
	}
	t := reflect.TypeOf(dst)
	if t.Kind() == reflect.Ptr {
		t = t.Elem()
	}
	return fmt.Sprintf("type:%s.%s", t.PkgPath(), t.Name())
}
