// Package memory owns persistence for resource-runtime managed Memory
// assets, human grants, agent bindings, pins, and asset-access outbox records.
//
// It is distinct from AgentTeam server agent-memory orchestration, daemon-local
// recovery memory, generic agent state, and API DTOs.
package memory

import "time"

// Memory is the persistence model for one managed resource-runtime Memory
// asset. Repository identity and content remain in their dedicated owners.
type Memory struct {
	ID                          string     `gorm:"primaryKey;size:64;index:idx_memories_exact_content,priority:1"`
	AgentID                     *string    `gorm:"size:64;uniqueIndex:uk_mem_agent"`
	Slug                        string     `gorm:"size:255;not null;default:'';index"`
	Name                        string     `gorm:"size:255;not null"`
	Description                 string     `gorm:"type:text;not null"`
	StorageScope                string     `gorm:"size:32;not null;default:'personal'"`
	StorageOwnerLogin           string     `gorm:"size:128;not null;default:''"`
	IsActive                    bool       `gorm:"not null;default:true;index"`
	Branch                      string     `gorm:"size:255;not null;default:'main'"`
	ContentID                   string     `gorm:"size:64;not null;default:'';index:idx_memories_exact_content,priority:2"`
	ActiveContentVersionID      string     `gorm:"size:64;not null;default:'';index:idx_memories_exact_content,priority:3"`
	ContentGeneration           uint64     `gorm:"not null;default:0;index:idx_memories_exact_content,priority:4"`
	ContentHistorySequence      uint64     `gorm:"not null;default:0"`
	ActiveReplicaID             string     `gorm:"size:128;not null;default:''"`
	AcknowledgedSequence        uint64     `gorm:"not null;default:0"`
	ImportExistingLocalContent  bool       `gorm:"not null;default:false"`
	ReplaceLocalContentOnSwitch bool       `gorm:"not null;default:false"`
	CreatedBy                   string     `gorm:"size:64;not null;index"`
	UpdatedBy                   string     `gorm:"size:64;not null"`
	CreatedAt                   time.Time  `gorm:"not null"`
	UpdatedAt                   time.Time  `gorm:"not null;index"`
	DeletedAt                   *time.Time `gorm:"index"`
	Pinned                      bool       `gorm:"-"`
	PinnedAt                    *time.Time `gorm:"-"`
	Role                        string     `gorm:"-"`
	CanManage                   bool       `gorm:"-"`
}

func (Memory) TableName() string { return "memories" }

// MemoryContentCheckpoint is the Memory-owned projection of one exact cloud
// ContentVersion. The immutable tree payload remains owned by Content Store;
// this row records only the binding, checkpoint acknowledgement, and bounded
// summary needed for restart-safe sync and history.
type MemoryContentCheckpoint struct {
	ID                     string     `gorm:"primaryKey;size:64;index:idx_memory_content_history,priority:4"`
	WorkspaceID            string     `gorm:"size:64;not null;index:idx_memory_content_history,priority:1;uniqueIndex:uk_memory_content_history_sequence,priority:1;uniqueIndex:uk_memory_content_version,priority:1;uniqueIndex:uk_memory_content_operation,priority:1;index:idx_memory_content_lineage,priority:1"`
	MemoryID               string     `gorm:"size:64;not null;index:idx_memory_content_history,priority:2;uniqueIndex:uk_memory_content_history_sequence,priority:2;uniqueIndex:uk_memory_content_version,priority:2;uniqueIndex:uk_memory_content_operation,priority:2"`
	ContentID              string     `gorm:"size:64;not null;uniqueIndex:uk_memory_content_version,priority:3;index:idx_memory_content_lineage,priority:2"`
	ContentVersionID       string     `gorm:"size:64;not null;uniqueIndex:uk_memory_content_version,priority:4;index:idx_memory_content_lineage,priority:3"`
	ParentContentVersionID string     `gorm:"size:64;not null;default:''"`
	TargetContentVersionID string     `gorm:"size:64;not null;default:''"`
	OperationID            string     `gorm:"size:128;not null;uniqueIndex:uk_memory_content_operation,priority:3"`
	OperationKind          string     `gorm:"size:32;not null"`
	ReplicaID              string     `gorm:"size:128;not null;default:''"`
	CoveredFromSequence    uint64     `gorm:"not null;default:0"`
	CoveredThroughSequence uint64     `gorm:"not null;default:0"`
	Generation             uint64     `gorm:"not null"`
	HistorySequence        uint64     `gorm:"not null;uniqueIndex:uk_memory_content_history_sequence,priority:3;index:idx_memory_content_history,priority:3"`
	RootDigest             string     `gorm:"size:64;not null"`
	FileCount              int        `gorm:"not null"`
	SizeBytes              int64      `gorm:"not null"`
	SourceAuthorName       string     `gorm:"size:255;not null;default:''"`
	SourceAuthorEmail      string     `gorm:"size:255;not null;default:''"`
	SourceAuthoredAt       *time.Time `gorm:"index"`
	SourceMessage          string     `gorm:"type:text;not null"`
	CreatedBy              string     `gorm:"size:64;not null"`
	CreatedAt              time.Time  `gorm:"not null"`
}

func (MemoryContentCheckpoint) TableName() string { return "memory_content_checkpoints" }

// MemoryGrant persists one human product-access grant for a managed Memory.
// Service policy remains responsible for interpreting and authorizing roles.
type MemoryGrant struct {
	ID          string    `gorm:"primaryKey;size:64"`
	WorkspaceID string    `gorm:"size:64;not null;index:idx_mem_grants_subject;uniqueIndex:uk_mem_grants_subject"`
	MemoryID    string    `gorm:"size:64;not null;index:idx_mem_grants_memory;uniqueIndex:uk_mem_grants_subject"`
	SubjectType string    `gorm:"size:32;not null;index:idx_mem_grants_subject;uniqueIndex:uk_mem_grants_subject"`
	SubjectID   string    `gorm:"size:64;not null;index:idx_mem_grants_subject;uniqueIndex:uk_mem_grants_subject"`
	Role        string    `gorm:"size:32;not null;default:'view'"`
	CreatedBy   string    `gorm:"size:64;not null"`
	UpdatedBy   string    `gorm:"size:64;not null"`
	CreatedAt   time.Time `gorm:"not null"`
	UpdatedAt   time.Time `gorm:"not null;index"`
}

func (MemoryGrant) TableName() string { return "memory_grants" }

// MemoryAgentBinding is the store projection synthesized from
// memories.agent_id for the one-to-one managed Memory-to-agent relationship.
// It is not generic agent state or daemon-local Memory state.
type MemoryAgentBinding struct {
	ID                          string
	WorkspaceID                 string
	AgentID                     string
	MemoryID                    string
	Branch                      string
	ImportExistingLocalContent  bool
	ReplaceLocalContentOnSwitch bool
	CreatedBy                   string
	UpdatedBy                   string
	CreatedAt                   time.Time
	UpdatedAt                   time.Time
}

// AgentAssetAccessChangeOutbox is the durable service-side delivery intent
// emitted whenever an agent's managed local assets need to be refreshed on
// Desktop. The table is intentionally generic so Memory and Skill access
// changes can share the same daemon event contract.
type AgentAssetAccessChangeOutbox struct {
	ID             string     `gorm:"primaryKey;size:64"`
	WorkspaceID    string     `gorm:"size:64;not null;index:idx_agent_asset_access_workspace_status;index:idx_agent_asset_access_agent_version,priority:1"`
	AgentID        string     `gorm:"size:64;not null;index:idx_agent_asset_access_agent_version,priority:2"`
	AssetType      string     `gorm:"size:32;not null;index:idx_agent_asset_access_agent_version,priority:3"`
	Version        int64      `gorm:"not null;index:idx_agent_asset_access_agent_version,priority:4"`
	Source         string     `gorm:"size:32;not null;default:'outbox'"`
	Status         string     `gorm:"size:32;not null;default:'pending';index:idx_agent_asset_access_workspace_status;index:idx_agent_asset_access_status_next,priority:1"`
	Attempts       int        `gorm:"not null;default:0"`
	MaxAttempts    int        `gorm:"not null;default:10"`
	NextAttemptAt  time.Time  `gorm:"not null;index:idx_agent_asset_access_status_next,priority:2"`
	LeaseOwner     string     `gorm:"size:128;not null;default:''"`
	LeaseExpiresAt *time.Time `gorm:"index"`
	LastError      string     `gorm:"type:text;not null"`
	OccurredAt     time.Time  `gorm:"not null"`
	DeliveredAt    *time.Time `gorm:"index"`
	CreatedAt      time.Time  `gorm:"not null"`
	UpdatedAt      time.Time  `gorm:"not null;index"`
}

func (AgentAssetAccessChangeOutbox) TableName() string {
	return "agent_asset_access_change_outbox"
}

// MemoryPin persists one principal's collection pin for a managed Memory.
type MemoryPin struct {
	WorkspaceID string    `gorm:"primaryKey;size:64"`
	PrincipalID string    `gorm:"primaryKey;size:64"`
	MemoryID    string    `gorm:"primaryKey;size:64;index"`
	CreatedAt   time.Time `gorm:"not null"`
	UpdatedAt   time.Time `gorm:"not null;index"`
}

func (MemoryPin) TableName() string { return "memory_pins" }
