package adapter

import (
	"context"
	"encoding/json"
	"fmt"
	"time"

	"github.com/tidbcloud/tidb-management-service/serverless-global-service/domain/entity"
)

type Sys9Session struct {
	SessionToken     string
	AccessToken      string
	RequestContextID string
	ExpiresAt        time.Time
	RefreshAfter     time.Time
}

//go:generate go run go.uber.org/mock/mockgen@latest -source=$GOFILE -package=mock_$GOPACKAGE -destination=./mock_$GOPACKAGE/mock_$GOFILE
type Sys9AuthManager interface {
	GetSession(ctx context.Context, region *entity.Region) (*Sys9Session, error)
	Invalidate(ctx context.Context, region *entity.Region)
}

type Sys9OEMProfile struct {
	BrandID                string          `json:"brand_id"                  yaml:"brand_id"`
	AccountID              string          `json:"account_id"                yaml:"account_id"`
	Issuer                 string          `json:"issuer"                    yaml:"issuer"`
	Audience               string          `json:"audience"                  yaml:"audience"`
	Assertion              string          `json:"assertion"                 yaml:"assertion"`
	SubjectAnchor          string          `json:"subject_anchor"            yaml:"subject_anchor"`
	SubjectAnchorVersion   int64           `json:"subject_anchor_version"    yaml:"subject_anchor_version"`
	EntityAnchor           string          `json:"entity_anchor"             yaml:"entity_anchor"`
	EntityAnchorVersion    int64           `json:"entity_anchor_version"     yaml:"entity_anchor_version"`
	DPoPPublicKey          string          `json:"dpop_public_key"           yaml:"dpop_public_key"`
	TemporaryDPoPPublicKey string          `json:"temporary_dpop_public_key" yaml:"temporary_dpop_public_key"`
	DPoPProof              string          `json:"dpop_proof"                yaml:"dpop_proof"`
	TLSExporterDigest      string          `json:"tls_exporter_digest"       yaml:"tls_exporter_digest"`
	EdgeBinding            Sys9EdgeBinding `json:"edge_binding"              yaml:"edge_binding"`
	DevToken               string          `json:"dev_token"                 yaml:"dev_token"`
}

type Sys9EdgeBinding map[string]any

func (b *Sys9EdgeBinding) UnmarshalJSON(data []byte) error {
	if len(data) == 0 || string(data) == "null" {
		*b = nil
		return nil
	}

	var objectValue map[string]any
	if err := json.Unmarshal(data, &objectValue); err == nil {
		*b = Sys9EdgeBinding(objectValue)
		return nil
	}

	var jsonObjectString string
	if err := json.Unmarshal(data, &jsonObjectString); err != nil {
		return fmt.Errorf("edge_binding must be an object")
	}

	if err := json.Unmarshal([]byte(jsonObjectString), &objectValue); err != nil {
		return fmt.Errorf("edge_binding string must contain a JSON object")
	}

	*b = Sys9EdgeBinding(objectValue)
	return nil
}

//go:generate go run go.uber.org/mock/mockgen@latest -source=$GOFILE -package=mock_$GOPACKAGE -destination=./mock_$GOPACKAGE/mock_$GOFILE
type Sys9SecretProvider interface {
	ResolveProfile(ctx context.Context, profileRef string) (*Sys9OEMProfile, error)
}
