package storage

import (
	"context"

	"github.com/pingcap/kvproto/pkg/keyspacepb"
	inframysql "github.com/tidbcloud/tidb-management-service/api/serverless_infra/client/mysql"
)

type index string

const (
	IndexKeyspaceName index = "keyspace_name"
	IndexKeyspaceID   index = "keyspace_id"
	IndexClusterID    index = "cluster_id"
	IndexTenantID     index = "tenant_id"
	IndexProjectID    index = "project_id"
	IndexBillingPlan  index = "billing_plan"

	IndexKeyspaceToken        index = "keyspace_token"
	IndexZoneRedundantEnabled index = "zone_redundant_enabled"
)

// KeyspaceSupportedIndex is a list of supported index.
var KeyspaceSupportedIndex = []index{
	IndexKeyspaceName,
	IndexKeyspaceID,
	IndexClusterID,
	IndexTenantID,
	IndexProjectID,
	IndexBillingPlan,
}

// ClusterSupportedIndex is a list of supported index.
var ClusterSupportedIndex = []index{
	IndexKeyspaceToken,
	IndexKeyspaceID,
	IndexClusterID,
	IndexTenantID,
	IndexProjectID,
	IndexBillingPlan,
	IndexZoneRedundantEnabled,
}

type Storage interface {
	Start(ctx context.Context) error
	Close() error
	LookupKeyspace(index index, key string, enabledOnly bool) ([]*KeyspaceMetaData, error)
	LookupCluster(index index, key string) ([]*inframysql.Cluster, error)
	GetClusterEventWindow() (ClusterEventWindow, error)
	ListKeyspaces(filter KeyspaceListFilter) ([]*KeyspaceMetaData, error)
	// ListKeyspacesPaginated lists keyspaces with pagination. When limit <= 0, returns all; otherwise returns at most limit items from offset. total is total count matching filter.
	ListKeyspacesPaginated(filter KeyspaceListFilter, limit, offset int) (items []*KeyspaceMetaData, total int, err error)
}

type ClusterEvent struct {
	EventID         uint64 `json:"event_id"`
	Name            string `json:"name"`
	EventType       string `json:"event_type"`
	ResourceVersion uint64 `json:"resource_version"`
}

type ClusterEventWindow struct {
	// Epoch identifies one process-local event-window generation.
	Epoch            string `json:"epoch"`
	HighWatermark    uint64 `json:"high_watermark"`
	RewindLowerBound uint64 `json:"rewind_lower_bound"`
	// Events is the complete process-local snapshot, sorted by EventID, with one maximum entry per cluster.
	Events []ClusterEvent `json:"events"`
}

type KeyspaceListFilter struct {
	HasState bool
	State    keyspacepb.KeyspaceState
}

func (f KeyspaceListFilter) Empty() bool {
	return !f.HasState
}
