// Package repotokens owns persistence for repository-scoped AGS
// and sync credentials and their audit and agent-suppression records.
//
// It does not own personal access tokens, login or session authentication,
// generic authorization, resource-to-repository bindings, or API DTOs.
package repotokens

import "time"

// Token stores repository-scoped AGS or sync credential metadata and an
// irreversible verifier. Plaintext credentials are returned once and are never
// persisted. Token is a persistence model, not an API DTO or session token.
type Token struct {
	ID                  uint   `gorm:"primaryKey;autoIncrement"`
	PublicID            string `gorm:"uniqueIndex;size:64;not null"`
	AGSTokenID          string `gorm:"uniqueIndex;size:64;not null"`
	VerifierHash        string `gorm:"uniqueIndex;size:128;not null"`
	Fingerprint         string `gorm:"size:32;not null;index"`
	Type                string `gorm:"size:16;not null;index:idx_repository_access_tokens_owner_list,priority:3"`
	DisplayName         string `gorm:"size:255;not null"`
	OwnerPrincipalID    string `gorm:"size:255;not null;index:idx_repository_access_tokens_owner_list,priority:2"`
	WorkspaceID         string `gorm:"size:128;not null;index:idx_repository_access_tokens_owner_list,priority:1;index:idx_repository_access_tokens_agent,priority:1"`
	AgentID             string `gorm:"size:128;index:idx_repository_access_tokens_agent,priority:2"`
	ProviderHost        string `gorm:"size:255;not null;index"`
	RepositoryScopeJSON string `gorm:"type:text;not null"`
	CapabilitiesJSON    string `gorm:"type:text;not null"`
	Status              string `gorm:"size:32;not null;index"`
	CreatedAt           time.Time
	UpdatedAt           time.Time
	LastUsedAt          *time.Time `gorm:"index"`
	ExpiresAt           *time.Time `gorm:"index"`
	RevokedAt           *time.Time `gorm:"index"`
}

func (Token) TableName() string { return "repository_access_tokens" }

// Event records a bounded, non-secret repository credential audit fact.
// It is persisted with the credential lifecycle and is not an API event DTO.
type Event struct {
	ID               uint      `gorm:"primaryKey;autoIncrement"`
	EventID          string    `gorm:"uniqueIndex;size:64;not null"`
	TokenID          uint      `gorm:"index:idx_repository_access_token_events_token_created,priority:1;not null"`
	PublicTokenID    string    `gorm:"size:64;not null;index"`
	AGSTokenID       string    `gorm:"size:64;not null;index"`
	Type             string    `gorm:"size:64;not null;index"`
	ActorPrincipalID string    `gorm:"size:255;not null;index"`
	MetadataJSON     string    `gorm:"type:text"`
	CreatedAt        time.Time `gorm:"index:idx_repository_access_token_events_token_created,priority:2;index"`
}

func (Event) TableName() string { return "repository_access_token_events" }

// AgentSuppression persists the decision that prevents a force-revoked agent
// repository credential from being silently recreated by later reconciliation.
type AgentSuppression struct {
	ID               uint   `gorm:"primaryKey;autoIncrement"`
	WorkspaceID      string `gorm:"size:128;not null;uniqueIndex:uidx_repository_access_token_agent_suppression"`
	AgentID          string `gorm:"size:128;not null;uniqueIndex:uidx_repository_access_token_agent_suppression"`
	ActorPrincipalID string `gorm:"size:255;not null"`
	Reason           string `gorm:"size:255"`
	CreatedAt        time.Time
	UpdatedAt        time.Time
	SuppressedAt     time.Time `gorm:"index"`
}

func (AgentSuppression) TableName() string {
	return "repository_access_token_agent_suppressions"
}
