package storage

import (
	"maps"
	"strconv"

	"github.com/gogo/protobuf/proto"
	"github.com/pingcap/kvproto/pkg/keyspacepb"
)

const (
	clusterIDTag  = "serverless_cluster_id"
	projectIDTag  = "serverless_project_id"
	tenantIDTag   = "serverless_tenant_id"
	isBranchTag   = "serverless_is_branch"
	encryptionTag = "encryption"

	tsoKeyspaceGroupTag = "tso_keyspace_group_id"
)

type KeyspaceMetaData struct {
	// using string for keyspaceID for better handle.
	KeyspaceID     string
	KeyspaceName   string
	ClusterId      string
	TenantID       string
	ProjectID      string
	Encrypted      bool
	IsBranch       bool
	MinRCU         int64
	MaxRCU         int64
	RuVersion      string
	State          keyspacepb.KeyspaceState
	CreatedAt      int64
	StateChangedAt int64
	Config         map[string]string

	TsoKeyspaceGroupID string
}

func (meta *KeyspaceMetaData) IsEssential() bool {
	return meta.MaxRCU > 0 || meta.MinRCU > 0
}

/*
branch
{
    "id": 152261,
    "name": "ZZgoBVvDZoDrsm2",
    "state": "ENABLED",
    "created_at": 1741158802,
    "state_changed_at": 1741158802,
    "config": {
        "gc_life_time": "6000",
        "safe_point_version": "v2",
        "serverless_cluster_id": "bran-xwxd7l3o6nhcfgsdxfphhshkni",
        "serverless_is_branch": "True",
        "serverless_is_branch_bootstrapped": "True",
        "serverless_project_id": "2863503",
        "serverless_tenant_id": "30018",
        "tso_keyspace_group_id": "0",
        "user_kind": "basic"
    }
}
normal cluster
{
    "id": 147117,
    "name": "2DsNjQuYwVFiz4v",
    "state": "ENABLED",
    "created_at": 1736489712,
    "state_changed_at": 1736489712,
    "config": {
        "gc_life_time": "6000",
        "safe_point_version": "v2",
        "serverless_cluster_id": "10284428281942126981",
        "serverless_project_id": "2863503",
        "serverless_tenant_id": "30018",
        "tso_keyspace_group_id": "1",
        "user_kind": "basic"
    }
}
encrypted
{
    "id": 147880,
    "name": "2PdLwgiZiCrphLp",
    "state": "ENABLED",
    "created_at": 1737342435,
    "state_changed_at": 1737342435,
    "config": {
        "encryption": "{\"enabled\":true}",
        "gc_life_time": "6000",
        "safe_point_version": "v2",
        "serverless_cluster_id": "10875356906442252622",
        "serverless_project_id": "2863503",
        "serverless_tenant_id": "30018",
        "tso_keyspace_group_id": "1",
        "user_kind": "basic"
    }
}
*/
// getKeyspaceMeta unmarshalls the protobuf stored in etcd and transform it into metadata.
func getKeyspaceMeta(data []byte) (*KeyspaceMetaData, error) {
	var keyspaceMeta keyspacepb.KeyspaceMeta
	if err := proto.Unmarshal(data, &keyspaceMeta); err != nil {
		return nil, err
	}
	meta := &KeyspaceMetaData{
		KeyspaceID:   strconv.FormatUint(uint64(keyspaceMeta.GetId()), 10),
		KeyspaceName: keyspaceMeta.GetName(),
		ClusterId:    keyspaceMeta.GetConfig()[clusterIDTag],
		TenantID:     keyspaceMeta.GetConfig()[tenantIDTag],
		ProjectID:    keyspaceMeta.GetConfig()[projectIDTag],

		TsoKeyspaceGroupID: keyspaceMeta.GetConfig()[tsoKeyspaceGroupTag],
		State:              keyspaceMeta.GetState(),
		CreatedAt:          keyspaceMeta.GetCreatedAt(),
		StateChangedAt:     keyspaceMeta.GetStateChangedAt(),
		Config:             maps.Clone(keyspaceMeta.GetConfig()),
	}
	if keyspaceMeta.Config[isBranchTag] == "True" {
		meta.IsBranch = true
	}
	if keyspaceMeta.Config[encryptionTag] != "" {
		meta.Encrypted = true
	}
	meta.MinRCU, _ = strconv.ParseInt(keyspaceMeta.GetConfig()["min_rcu"], 10, 32)
	meta.MaxRCU, _ = strconv.ParseInt(keyspaceMeta.GetConfig()["max_rcu"], 10, 32)
	meta.RuVersion = keyspaceMeta.GetConfig()["ru_version"]
	return meta, nil
}
