package db

import "time"

// RepositoryPushRecovery is the single bounded, durable in-flight
// receive-pack operation for a repository. It is written before the Git child
// starts and removed atomically with outbox publication after reconciliation.
// It intentionally has no Repository foreign key so repository lifecycle
// cleanup cannot erase crash-recovery evidence.
type RepositoryPushRecovery struct {
	RepositoryID  uint      `gorm:"primaryKey;autoIncrement:false;index:idx_repository_push_recovery_claim,priority:3"`
	OperationID   string    `gorm:"size:64;not null;uniqueIndex"`
	Epoch         uint64    `gorm:"not null"`
	ActorID       uint      `gorm:"not null;default:0"`
	OccurredAt    time.Time `gorm:"not null"`
	CommandsJSON  LargeText
	State         string     `gorm:"size:16;not null;index:idx_repository_push_recovery_claim,priority:1"`
	NextAttemptAt time.Time  `gorm:"not null;index:idx_repository_push_recovery_claim,priority:2"`
	LeaseUntil    *time.Time `gorm:"index"`
	LeaseToken    string     `gorm:"size:64;index"`
	Attempts      uint       `gorm:"not null;default:0"`
	LastError     string     `gorm:"size:1024"`
	CreatedAt     time.Time
	UpdatedAt     time.Time
}

func (RepositoryPushRecovery) TableName() string {
	return "repository_push_recovery"
}

// RepositoryPushOutbox is the idempotent, bounded post-push event produced in
// the same transaction that clears RepositoryPushRecovery.
type RepositoryPushOutbox struct {
	ID             uint      `gorm:"primaryKey;autoIncrement;index:idx_repository_push_outbox_claim,priority:3"`
	RepositoryID   uint      `gorm:"not null;index"`
	OperationID    string    `gorm:"size:64;not null;uniqueIndex:idx_repository_push_outbox_operation_event,priority:1"`
	EventKey       string    `gorm:"size:64;not null;uniqueIndex:idx_repository_push_outbox_operation_event,priority:2"`
	ActorID        uint      `gorm:"not null;default:0"`
	OccurredAt     time.Time `gorm:"not null"`
	RefUpdatesJSON LargeText
	State          string     `gorm:"size:16;not null;index:idx_repository_push_outbox_claim,priority:1"`
	NextAttemptAt  time.Time  `gorm:"not null;index:idx_repository_push_outbox_claim,priority:2"`
	LeaseUntil     *time.Time `gorm:"index"`
	LeaseToken     string     `gorm:"size:64;index"`
	Attempts       uint       `gorm:"not null;default:0"`
	LastError      string     `gorm:"size:1024"`
	CreatedAt      time.Time
	UpdatedAt      time.Time
}

func (RepositoryPushOutbox) TableName() string {
	return "repository_push_outbox"
}
