package dto

import (
	"encoding/json"

	"github.com/tidbcloud/AgentTeam/internal/service/automation"
)

// AutomationRunList is a paginated response for listing automation runs.
type AutomationRunList struct {
	Items   []AutomationRun `json:"items"`
	HasMore bool            `json:"hasMore"`
}

// AutomationRun is the frontend-facing MeshX automation run ledger response.
type AutomationRun struct {
	ID                   string                                `json:"id"`
	WorkspaceID          string                                `json:"workspaceId"`
	IdempotencyKey       string                                `json:"idempotencyKey,omitempty"`
	SourceKind           string                                `json:"sourceKind,omitempty"`
	ContentID            string                                `json:"contentId,omitempty"`
	ContentVersionID     string                                `json:"contentVersionId,omitempty"`
	RepositoryOwner      string                                `json:"repositoryOwner,omitempty"`
	RepositoryName       string                                `json:"repositoryName,omitempty"`
	RepositoryFullName   string                                `json:"repositoryFullName,omitempty"`
	DefinitionPath       string                                `json:"definitionPath,omitempty"`
	GitRef               string                                `json:"gitRef,omitempty"`
	CommitSHA            string                                `json:"commitSha,omitempty"`
	DefinitionID         string                                `json:"definitionId,omitempty"`
	Name                 string                                `json:"name"`
	RunName              string                                `json:"runName,omitempty"`
	Status               string                                `json:"status"`
	InputJSON            string                                `json:"inputJson,omitempty"`
	OutputJSON           string                                `json:"outputJson,omitempty"`
	ErrorJSON            string                                `json:"errorJson,omitempty"`
	Error                *automation.AutomationStructuredError `json:"error,omitempty"`
	TriggerKind          string                                `json:"triggerKind,omitempty"`
	TriggerRef           string                                `json:"triggerRef,omitempty"`
	TriggerContext       *AutomationTriggerContext             `json:"triggerContext,omitempty"`
	TargetKind           string                                `json:"targetKind,omitempty"`
	TargetRef            string                                `json:"targetRef,omitempty"`
	OwnerPrincipalID     string                                `json:"ownerPrincipalId"`
	CreatedByPrincipalID string                                `json:"createdByPrincipalId"`
	CurrentJobID         string                                `json:"currentJobId,omitempty"`
	Summary              string                                `json:"summary,omitempty"`
	Metadata             string                                `json:"metadata,omitempty"`
	StartedAt            string                                `json:"startedAt,omitempty"`
	CompletedAt          string                                `json:"completedAt,omitempty"`
	CreatedAt            string                                `json:"createdAt"`
	UpdatedAt            string                                `json:"updatedAt"`
}

type AutomationDashboard struct {
	ObservedAt     string                             `json:"observedAt"`
	Health         AutomationDashboardHealth          `json:"health"`
	Metrics        AutomationDashboardMetrics         `json:"metrics"`
	AttentionItems []AutomationDashboardAttentionItem `json:"attentionItems"`
}

type AutomationDashboardHealth struct {
	Status     string `json:"status"`
	IssueCount int    `json:"issueCount"`
}

type AutomationDashboardAttentionItem struct {
	Kind       string `json:"kind"`
	Severity   string `json:"severity"`
	Count      int64  `json:"count"`
	TargetPath string `json:"targetPath"`
}

type AutomationDashboardMetrics struct {
	ObservedAt    string                  `json:"observedAt"`
	QueueMetrics  AutomationQueueMetrics  `json:"queueMetrics"`
	RunMetrics    AutomationRunMetrics    `json:"runMetrics"`
	WaitMetrics   AutomationWaitMetrics   `json:"waitMetrics"`
	RunnerMetrics AutomationRunnerMetrics `json:"runnerMetrics"`
	BlobMetrics   AutomationBlobMetrics   `json:"blobMetrics"`
	Reconciler    AutomationReconciler    `json:"reconciler"`
}

type AutomationRunOverview struct {
	ObservedAt     string                       `json:"observedAt"`
	Run            AutomationRun                `json:"run"`
	JobRuns        []AutomationJobRun           `json:"jobRuns"`
	QueueJobs      []AutomationQueueJob         `json:"queueJobs"`
	RunnerSessions []AutomationRunnerSessionRef `json:"runnerSessions"`
	Waits          []AutomationWait             `json:"waits"`
	Events         []AutomationEvent            `json:"events"`
	LogChunks      []AutomationLogChunk         `json:"logChunks"`
	Artifacts      []AutomationArtifact         `json:"artifacts"`
	BlobSummaries  []AutomationRunBlobSummary   `json:"blobSummaries"`
	Metrics        AutomationDashboardMetrics   `json:"metrics"`
}

type AutomationQueueMetrics struct {
	Ready         int64 `json:"ready"`
	Leased        int64 `json:"leased"`
	Done          int64 `json:"done"`
	Failed        int64 `json:"failed"`
	Canceled      int64 `json:"canceled"`
	ExpiredLeases int64 `json:"expiredLeases"`
	RetryReady    int64 `json:"retryReady"`
}

type AutomationRunMetrics struct {
	Queued               int64 `json:"queued"`
	Running              int64 `json:"running"`
	Waiting              int64 `json:"waiting"`
	Blocked              int64 `json:"blocked"`
	Failed               int64 `json:"failed"`
	Succeeded            int64 `json:"succeeded"`
	Canceled             int64 `json:"canceled"`
	ActiveSlots          int64 `json:"activeSlots"`
	LeakedActiveSlots    int64 `json:"leakedActiveSlots"`
	TerminalInconsistent int64 `json:"terminalInconsistent"`
}

type AutomationWaitMetrics struct {
	Active           int64 `json:"active"`
	Resolved         int64 `json:"resolved"`
	Canceled         int64 `json:"canceled"`
	ActiveAgentTasks int64 `json:"activeAgentTasks"`
	ActiveEventWaits int64 `json:"activeEventWaits"`
}

type AutomationRunnerMetrics struct {
	Registered      int64 `json:"registered"`
	Active          int64 `json:"active"`
	Revoked         int64 `json:"revoked"`
	ActiveSessions  int64 `json:"activeSessions"`
	ExpiredSessions int64 `json:"expiredSessions"`
	RevokedSessions int64 `json:"revokedSessions"`
}

type AutomationBlobMetrics struct {
	LogChunks        int64 `json:"logChunks"`
	Artifacts        int64 `json:"artifacts"`
	ExpiredArtifacts int64 `json:"expiredArtifacts"`
}

type AutomationReconciler struct {
	LastStartedAt       string                    `json:"lastStartedAt,omitempty"`
	LastCompletedAt     string                    `json:"lastCompletedAt,omitempty"`
	LastSuccessAt       string                    `json:"lastSuccessAt,omitempty"`
	LastFailureAt       string                    `json:"lastFailureAt,omitempty"`
	LastError           string                    `json:"lastError,omitempty"`
	ErrorCount          uint64                    `json:"errorCount"`
	ConsecutiveFailures uint64                    `json:"consecutiveFailures"`
	LastResult          AutomationReconcileResult `json:"lastResult"`
}

type AutomationReconcileResult struct {
	StartedAt              string `json:"startedAt,omitempty"`
	CompletedAt            string `json:"completedAt,omitempty"`
	RecoveredExpiredJobs   int64  `json:"recoveredExpiredJobs"`
	ReconciledDependencies int64  `json:"reconciledDependencies"`
	ReconciledRuns         int64  `json:"reconciledRuns"`
	RepairedActiveRunSlots int64  `json:"repairedActiveRunSlots"`
}

type AutomationQueueJob struct {
	ID             int64  `json:"id"`
	WorkspaceID    string `json:"workspaceId"`
	RunID          string `json:"runId"`
	JobRunID       string `json:"jobRunId"`
	QueueName      string `json:"queueName"`
	Status         string `json:"status"`
	Priority       int    `json:"priority"`
	ScheduledAt    string `json:"scheduledAt"`
	NotBefore      string `json:"notBefore,omitempty"`
	LeaseOwner     string `json:"leaseOwner,omitempty"`
	LeaseUntil     string `json:"leaseUntil,omitempty"`
	Attempt        int    `json:"attempt"`
	MaxAttempts    int    `json:"maxAttempts"`
	RunnerGroup    string `json:"runnerGroup,omitempty"`
	RunnerGroupKey string `json:"runnerGroupKey,omitempty"`
	LabelsJSON     string `json:"labelsJson,omitempty"`
	LabelKey       string `json:"labelKey,omitempty"`
	LabelCount     int    `json:"labelCount"`
	ShardBucket    int    `json:"shardBucket"`
	CreatedAt      string `json:"createdAt"`
	UpdatedAt      string `json:"updatedAt"`
}

type AutomationRunnerSessionRef struct {
	WorkspaceID string `json:"workspaceId"`
	RunnerID    string `json:"runnerId"`
	SessionID   string `json:"sessionId"`
	LeaseOwner  string `json:"leaseOwner"`
	RunnerGroup string `json:"runnerGroup,omitempty"`
	LabelsJSON  string `json:"labelsJson,omitempty"`
	Status      string `json:"status"`
	HeartbeatAt string `json:"heartbeatAt,omitempty"`
	ExpiresAt   string `json:"expiresAt"`
	RevokedAt   string `json:"revokedAt,omitempty"`
	CreatedAt   string `json:"createdAt"`
	UpdatedAt   string `json:"updatedAt"`
}

type AutomationRunBlobSummary struct {
	JobRunID         string `json:"jobRunId"`
	LogChunks        int64  `json:"logChunks"`
	LogBytes         int64  `json:"logBytes"`
	ArtifactCount    int64  `json:"artifactCount"`
	ArtifactBytes    int64  `json:"artifactBytes"`
	LatestLogAt      string `json:"latestLogAt,omitempty"`
	LatestArtifactAt string `json:"latestArtifactAt,omitempty"`
}

// AutomationRepositoryRunRequest starts a MeshX-controlled run from an AGS repo automation file snapshot.
type AutomationRepositoryRunRequest struct {
	GitRef         string          `json:"ref"`
	DefinitionPath string          `json:"definitionPath"`
	IdempotencyKey string          `json:"idempotencyKey"`
	Name           string          `json:"name"`
	RunName        string          `json:"runName"`
	InputJSON      string          `json:"inputJson"`
	InputsJSON     string          `json:"inputs"`
	Branch         string          `json:"branch,omitempty"`
	BeforeSHA      string          `json:"beforeSha,omitempty"`
	ActorRef       string          `json:"actorRef,omitempty"`
	ActorDisplay   string          `json:"actorDisplay,omitempty"`
	TriggerKind    string          `json:"triggerKind"`
	TriggerRef     string          `json:"triggerRef"`
	TriggerContext json.RawMessage `json:"triggerContext,omitempty"`
	TargetKind     string          `json:"targetKind"`
	TargetRef      string          `json:"targetRef"`
}

func (request AutomationRepositoryRunRequest) Input(owner, repo string, authorizationHeader string) automation.AutomationRepositoryRunMutation {
	return automation.AutomationRepositoryRunMutation{
		RepositoryOwner:     owner,
		RepositoryName:      repo,
		DefinitionPath:      request.DefinitionPath,
		GitRef:              request.GitRef,
		Branch:              request.Branch,
		BeforeSHA:           request.BeforeSHA,
		ActorRef:            request.ActorRef,
		ActorDisplay:        request.ActorDisplay,
		AuthorizationHeader: authorizationHeader,
		IdempotencyKey:      request.IdempotencyKey,
		Name:                request.Name,
		RunName:             request.RunName,
		InputJSON:           firstNonEmpty(request.InputJSON, request.InputsJSON),
		TriggerKind:         request.TriggerKind,
		TriggerRef:          request.TriggerRef,
		TriggerContextJSON:  string(request.TriggerContext),
		TargetKind:          request.TargetKind,
		TargetRef:           request.TargetRef,
	}
}

// AutomationRepositoryPushEventRequest starts matching repository automation runs
// from a normalized repository branch-update event.
type AutomationRepositoryPushEventRequest struct {
	EventID      string          `json:"eventId,omitempty"`
	DeliveryKey  string          `json:"deliveryKey,omitempty"`
	Ref          string          `json:"ref"`
	Before       string          `json:"before,omitempty"`
	After        string          `json:"after"`
	ChangedPaths *[]string       `json:"changedPaths,omitempty"`
	ActorRef     string          `json:"actorRef,omitempty"`
	ActorDisplay string          `json:"actorDisplay,omitempty"`
	Sender       string          `json:"sender,omitempty"`
	EventPayload json.RawMessage `json:"eventPayload,omitempty"`
}

func (request AutomationRepositoryPushEventRequest) Input(owner, repo string, authorizationHeader string) automation.AutomationRepositoryPushEventMutation {
	eventPayloadJSON := ""
	if len(request.EventPayload) > 0 {
		eventPayloadJSON = string(request.EventPayload)
	}
	var changedPaths []string
	if request.ChangedPaths != nil {
		changedPaths = *request.ChangedPaths
	}
	return automation.AutomationRepositoryPushEventMutation{
		RepositoryOwner:     owner,
		RepositoryName:      repo,
		AuthorizationHeader: authorizationHeader,
		EventID:             request.EventID,
		DeliveryKey:         request.DeliveryKey,
		Ref:                 request.Ref,
		Before:              request.Before,
		After:               request.After,
		ChangedPaths:        changedPaths,
		ActorRef:            request.ActorRef,
		ActorDisplay:        request.ActorDisplay,
		Sender:              request.Sender,
		EventPayloadJSON:    eventPayloadJSON,
	}
}

// AutomationRepositoryPushEventResponse returns the runs created or replayed for
// one normalized repository branch-update event.
type AutomationRepositoryPushEventResponse struct {
	Runs []AutomationRun `json:"runs"`
}

// AutomationTriggerContext is the public API projection of Automation run
// trigger provenance. The service/store metadata keeps its internal JSON
// contract separately; DTO fields stay first-party camelCase.
type AutomationTriggerContext struct {
	TriggerKind          string `json:"triggerKind,omitempty"`
	RepositoryFullName   string `json:"repositoryFullName,omitempty"`
	Ref                  string `json:"ref,omitempty"`
	Branch               string `json:"branch,omitempty"`
	BeforeSHA            string `json:"beforeSha,omitempty"`
	AfterSHA             string `json:"afterSha,omitempty"`
	ActorRef             string `json:"actorRef,omitempty"`
	ActorDisplay         string `json:"actorDisplay,omitempty"`
	EventID              string `json:"eventId,omitempty"`
	ScheduleDefinitionID string `json:"scheduleDefinitionId,omitempty"`
	AutomationRunID      string `json:"automationRunId,omitempty"`
	RawPayloadRef        string `json:"rawPayloadRef,omitempty"`
}

type AutomationSourceRepository struct {
	ID            int64  `json:"id,omitempty"`
	Owner         string `json:"owner"`
	Name          string `json:"name"`
	FullName      string `json:"fullName"`
	DefaultBranch string `json:"defaultBranch,omitempty"`
	Private       bool   `json:"private"`
	HTMLURL       string `json:"htmlUrl,omitempty"`
}

type AutomationSourceFile struct {
	RepositoryOwner  string `json:"repositoryOwner"`
	RepositoryName   string `json:"repositoryName"`
	Path             string `json:"path"`
	Name             string `json:"name"`
	SHA              string `json:"sha,omitempty"`
	Size             int64  `json:"size"`
	Ref              string `json:"ref,omitempty"`
	ContentID        string `json:"contentId,omitempty"`
	ContentVersionID string `json:"contentVersionId,omitempty"`
}

type AutomationSourceContent struct {
	AutomationSourceFile
	Content  string `json:"content"`
	Encoding string `json:"encoding,omitempty"`
}

type AutomationSourceSaveRequest struct {
	Content string `json:"content"`
	Message string `json:"message,omitempty"`
	Branch  string `json:"branch,omitempty"`
	GitRef  string `json:"ref,omitempty"`
	SHA     string `json:"sha,omitempty"`
}

func (request AutomationSourceSaveRequest) Input(owner, repo, definitionPath string, authorizationHeader string) automation.AutomationRepositoryAutomationSaveMutation {
	return automation.AutomationRepositoryAutomationSaveMutation{RepositoryOwner: owner, RepositoryName: repo, DefinitionPath: definitionPath, Content: request.Content, Message: request.Message, Branch: request.Branch, GitRef: request.GitRef, SHA: request.SHA, AuthorizationHeader: authorizationHeader}
}

type AutomationSourceDeleteRequest struct {
	Message string `json:"message,omitempty"`
	Branch  string `json:"branch,omitempty"`
	GitRef  string `json:"ref,omitempty"`
	SHA     string `json:"sha"`
}

func (request AutomationSourceDeleteRequest) Input(owner, repo, definitionPath string, authorizationHeader string) automation.AutomationRepositoryAutomationDeleteMutation {
	return automation.AutomationRepositoryAutomationDeleteMutation{RepositoryOwner: owner, RepositoryName: repo, DefinitionPath: definitionPath, Message: request.Message, Branch: request.Branch, GitRef: request.GitRef, SHA: request.SHA, AuthorizationHeader: authorizationHeader}
}

type AutomationSourceSavedContent struct {
	AutomationSourceFile
	Encoding string `json:"encoding,omitempty"`
}

type AutomationSourceCommit struct {
	SHA              string `json:"sha,omitempty"`
	ContentVersionID string `json:"contentVersionId,omitempty"`
	Message          string `json:"message,omitempty"`
}

type AutomationSourceSaveResponse struct {
	Content AutomationSourceSavedContent `json:"content"`
	Commit  AutomationSourceCommit       `json:"commit"`
}

type AutomationSourceValidateRequest struct {
	Content string `json:"content"`
}

func (request AutomationSourceValidateRequest) Input(owner, repo, definitionPath string) automation.AutomationRepositoryAutomationValidateMutation {
	return automation.AutomationRepositoryAutomationValidateMutation{RepositoryOwner: owner, RepositoryName: repo, DefinitionPath: definitionPath, Content: request.Content}
}

type AutomationSourcePreflightRequest struct {
	Scenario        string `json:"scenario"`
	Ref             string `json:"ref"`
	ContentOverride string `json:"contentOverride"`
	InputJSON       string `json:"inputJson"`
	Branch          string `json:"branch"`
}

func (request AutomationSourcePreflightRequest) Input(owner, repo, definitionPath, authorizationHeader string) automation.AutomationRepositoryAutomationPreflightMutation {
	return automation.AutomationRepositoryAutomationPreflightMutation{
		RepositoryOwner:     owner,
		RepositoryName:      repo,
		DefinitionPath:      definitionPath,
		GitRef:              request.Ref,
		Scenario:            request.Scenario,
		ContentOverride:     request.ContentOverride,
		InputJSON:           request.InputJSON,
		Branch:              request.Branch,
		AuthorizationHeader: authorizationHeader,
	}
}

// AutomationSecretList is the metadata-only response for repo-scoped secrets.
type AutomationSecretList struct {
	Items   []AutomationSecret `json:"items"`
	HasMore bool               `json:"hasMore"`
}

// AutomationSecret is metadata for a repo-scoped automation secret.
type AutomationSecret struct {
	WorkspaceID     string `json:"workspaceId"`
	Scope           string `json:"scope"`
	RepositoryOwner string `json:"repositoryOwner"`
	RepositoryName  string `json:"repositoryName"`
	Name            string `json:"name"`
	CreatedBy       string `json:"createdBy"`
	UpdatedBy       string `json:"updatedBy"`
	CreatedAt       string `json:"createdAt"`
	UpdatedAt       string `json:"updatedAt"`
}

// AutomationSecretPutRequest submits plaintext secret material for immediate encryption.
type AutomationSecretPutRequest struct {
	Value string `json:"value"`
}

func (request AutomationSecretPutRequest) Input(owner, repo, name string) automation.AutomationSecretMutation {
	return automation.AutomationSecretMutation{RepositoryOwner: owner, RepositoryName: repo, Name: name, Value: request.Value}
}

// AutomationJobRun is the frontend-facing durable automation job run ledger response.
type AutomationJobRun struct {
	ID            string                                `json:"id"`
	WorkspaceID   string                                `json:"workspaceId"`
	RunID         string                                `json:"runId"`
	JobID         string                                `json:"jobId"`
	JobType       string                                `json:"jobType"`
	Status        string                                `json:"status"`
	Attempt       int                                   `json:"attempt"`
	MaxAttempts   int                                   `json:"maxAttempts"`
	RunsOnJSON    string                                `json:"runsOnJson,omitempty"`
	InputJSON     string                                `json:"inputJson,omitempty"`
	OutputJSON    string                                `json:"outputJson,omitempty"`
	Error         *automation.AutomationStructuredError `json:"error,omitempty"`
	ErrorJSON     string                                `json:"errorJson,omitempty"`
	DependsOnJSON string                                `json:"dependsOnJson,omitempty"`
	LeaseOwner    string                                `json:"leaseOwner,omitempty"`
	LeaseUntil    string                                `json:"leaseUntil,omitempty"`
	ScheduledAt   string                                `json:"scheduledAt"`
	StartedAt     string                                `json:"startedAt,omitempty"`
	CompletedAt   string                                `json:"completedAt,omitempty"`
	CreatedAt     string                                `json:"createdAt"`
	UpdatedAt     string                                `json:"updatedAt"`
}

// AutomationEvent is the frontend-facing MeshX automation event ledger response.
type AutomationEvent struct {
	ID               string `json:"id"`
	WorkspaceID      string `json:"workspaceId"`
	RunID            string `json:"runId"`
	JobRunID         string `json:"jobRunId,omitempty"`
	EventType        string `json:"eventType"`
	ActorPrincipalID string `json:"actorPrincipalId,omitempty"`
	ResourceType     string `json:"resourceType,omitempty"`
	ResourceID       string `json:"resourceId,omitempty"`
	Summary          string `json:"summary,omitempty"`
	MetadataJSON     string `json:"metadataJson,omitempty"`
	CreatedAt        string `json:"createdAt"`
}

// AutomationLogChunk is automation log metadata stored outside the hot run ledger.
type AutomationLogChunk struct {
	ID          string `json:"id"`
	WorkspaceID string `json:"workspaceId"`
	RunID       string `json:"runId"`
	JobRunID    string `json:"jobRunId"`
	Stream      string `json:"stream"`
	Sequence    int64  `json:"sequence"`
	SizeBytes   int64  `json:"sizeBytes"`
	SHA256      string `json:"sha256,omitempty"`
	ContentType string `json:"contentType,omitempty"`
	CreatedAt   string `json:"createdAt"`
}

// AutomationLogChunkContent includes one log chunk payload.
type AutomationLogChunkContent struct {
	AutomationLogChunk
	Content string `json:"content"`
}

// AutomationArtifact is automation artifact metadata stored outside the hot run ledger.
type AutomationArtifact struct {
	ID          string `json:"id"`
	WorkspaceID string `json:"workspaceId"`
	RunID       string `json:"runId"`
	JobRunID    string `json:"jobRunId"`
	Name        string `json:"name"`
	SizeBytes   int64  `json:"sizeBytes"`
	SHA256      string `json:"sha256,omitempty"`
	ContentType string `json:"contentType,omitempty"`
	ExpiresAt   string `json:"expiresAt,omitempty"`
	CreatedAt   string `json:"createdAt"`
	UpdatedAt   string `json:"updatedAt"`
}

// AutomationArtifactContent includes one artifact payload encoded as base64.
type AutomationArtifactContent struct {
	AutomationArtifact
	ContentBase64 string `json:"contentBase64"`
}

// AutomationWait is a frontend-facing durable AgentTeam-native wait subscription.
type AutomationWait struct {
	ID              string `json:"id"`
	WorkspaceID     string `json:"workspaceId"`
	RunID           string `json:"runId"`
	JobRunID        string `json:"jobRunId"`
	WaitKind        string `json:"waitKind"`
	Status          string `json:"status"`
	ResourceType    string `json:"resourceType,omitempty"`
	ResourceID      string `json:"resourceId,omitempty"`
	ResumeEventType string `json:"resumeEventType,omitempty"`
	InputJSON       string `json:"inputJson,omitempty"`
	ResultJSON      string `json:"resultJson,omitempty"`
	CreatedBy       string `json:"createdBy,omitempty"`
	ResolvedBy      string `json:"resolvedBy,omitempty"`
	CreatedAt       string `json:"createdAt"`
	UpdatedAt       string `json:"updatedAt"`
	ResolvedAt      string `json:"resolvedAt,omitempty"`
	CanceledAt      string `json:"canceledAt,omitempty"`
}

type AutomationWaitResumeRequest struct {
	ResultJSON string `json:"resultJson"`
}

// AutomationWaitTaskCompleteRequest resumes a agentteam/agent-task wait when the linked task finishes.
type AutomationWaitTaskCompleteRequest struct {
	TaskID     string `json:"taskId,omitempty"`
	TaskNumber int64  `json:"taskNumber,omitempty"`
	Status     string `json:"status,omitempty"`
	ResultJSON string `json:"resultJson,omitempty"`
}

// AutomationWaitEventSignalRequest resumes a agentteam/wait-event wait from a AgentTeam/provider/schedule event.
type AutomationWaitEventSignalRequest struct {
	EventType    string `json:"eventType,omitempty"`
	ResourceType string `json:"resourceType,omitempty"`
	ResourceID   string `json:"resourceId,omitempty"`
	PayloadJSON  string `json:"payloadJson,omitempty"`
	ResultJSON   string `json:"resultJson,omitempty"`
}

// AutomationWaitSignalDeliverRequest delivers a AgentTeam/service event by resource identity.
type AutomationWaitSignalDeliverRequest struct {
	WaitKind     string `json:"waitKind"`
	EventType    string `json:"eventType,omitempty"`
	ResourceType string `json:"resourceType,omitempty"`
	ResourceID   string `json:"resourceId,omitempty"`
	TaskID       string `json:"taskId,omitempty"`
	TaskNumber   int64  `json:"taskNumber,omitempty"`
	Status       string `json:"status,omitempty"`
	PayloadJSON  string `json:"payloadJson,omitempty"`
	ResultJSON   string `json:"resultJson,omitempty"`
}

func (request AutomationWaitSignalDeliverRequest) Input() automation.AutomationWaitSignalMutation {
	return automation.AutomationWaitSignalMutation{
		WaitKind:     request.WaitKind,
		EventType:    request.EventType,
		ResourceType: request.ResourceType,
		ResourceID:   request.ResourceID,
		TaskID:       request.TaskID,
		TaskNumber:   request.TaskNumber,
		Status:       request.Status,
		PayloadJSON:  request.PayloadJSON,
		ResultJSON:   request.ResultJSON,
	}
}

type AutomationRunnerRegisterRequest struct {
	Name        string   `json:"name"`
	RunnerID    string   `json:"runnerId"`
	RunnerGroup string   `json:"runnerGroup"`
	Labels      []string `json:"labels"`
}

func (request AutomationRunnerRegisterRequest) Input(runnerID string) automation.AutomationRunnerRegisterMutation {
	return automation.AutomationRunnerRegisterMutation{Name: request.Name, RunnerID: firstNonEmpty(request.RunnerID, runnerID), RunnerGroup: request.RunnerGroup, Labels: request.Labels}
}

type AutomationRunnerRegistration struct {
	RunnerID          string   `json:"runnerId"`
	Name              string   `json:"name,omitempty"`
	RunnerGroup       string   `json:"runnerGroup,omitempty"`
	Labels            []string `json:"labels,omitempty"`
	RegistrationToken string   `json:"registrationToken"`
	TokenExpiresAt    string   `json:"tokenExpiresAt"`
	RegisteredAt      string   `json:"registeredAt"`
}

type AutomationRunnerSessionRequest struct {
	SessionID string `json:"sessionId"`
}

func (request AutomationRunnerSessionRequest) Input(runnerID string) automation.AutomationRunnerSessionMutation {
	return automation.AutomationRunnerSessionMutation{RunnerID: runnerID, SessionID: request.SessionID}
}

type AutomationRunnerSession struct {
	RunnerID     string `json:"runnerId"`
	SessionID    string `json:"sessionId"`
	LeaseOwner   string `json:"leaseOwner"`
	SessionToken string `json:"sessionToken"`
	HeartbeatAt  string `json:"heartbeatAt"`
	ExpiresAt    string `json:"expiresAt"`
	CreatedAt    string `json:"createdAt"`
}

type AutomationRunnerHeartbeatRequest struct {
	QueueJobID int64 `json:"queueJobId,omitempty"`
}

func (request AutomationRunnerHeartbeatRequest) Input(runnerID string, sessionID string) automation.AutomationRunnerHeartbeatMutation {
	return automation.AutomationRunnerHeartbeatMutation{RunnerID: runnerID, SessionID: sessionID, QueueJobID: request.QueueJobID}
}

type AutomationRunnerHeartbeat struct {
	RunnerID        string `json:"runnerId"`
	SessionID       string `json:"sessionId"`
	LeaseOwner      string `json:"leaseOwner"`
	HeartbeatAt     string `json:"heartbeatAt"`
	ExpiresAt       string `json:"expiresAt"`
	CancelRequested bool   `json:"cancelRequested"`
}

type AutomationRunnerAcquireRequest struct {
	RunnerID     string
	SessionID    string
	QueueName    string
	ShardBucket  *int
	Limit        int
	LeaseSeconds int
	WaitSeconds  int
}

func (request AutomationRunnerAcquireRequest) Input() automation.AutomationRunnerAcquireMutation {
	return automation.AutomationRunnerAcquireMutation{RunnerID: request.RunnerID, SessionID: request.SessionID, QueueName: request.QueueName, ShardBucket: request.ShardBucket, Limit: request.Limit, LeaseSeconds: request.LeaseSeconds, WaitSeconds: request.WaitSeconds}
}

type AutomationRunnerAcquireResponse struct {
	Jobs []AutomationRunnerJob `json:"jobs"`
}

type AutomationRunnerJob struct {
	QueueJobID         int64    `json:"queueJobId"`
	WorkspaceID        string   `json:"workspaceId"`
	RunID              string   `json:"runId"`
	JobRunID           string   `json:"jobRunId"`
	JobID              string   `json:"jobId"`
	QueueName          string   `json:"queueName"`
	Status             string   `json:"status"`
	Attempt            int      `json:"attempt"`
	MaxAttempts        int      `json:"maxAttempts"`
	LeaseOwner         string   `json:"leaseOwner"`
	LeaseUntil         string   `json:"leaseUntil,omitempty"`
	RepositoryOwner    string   `json:"repositoryOwner,omitempty"`
	RepositoryName     string   `json:"repositoryName,omitempty"`
	RepositoryFullName string   `json:"repositoryFullName,omitempty"`
	DefinitionPath     string   `json:"definitionPath,omitempty"`
	GitRef             string   `json:"gitRef,omitempty"`
	CommitSHA          string   `json:"commitSha,omitempty"`
	ContentID          string   `json:"contentId,omitempty"`
	ContentVersionID   string   `json:"contentVersionId,omitempty"`
	AutomationName     string   `json:"automationName,omitempty"`
	RunsOnJSON         string   `json:"runsOnJson,omitempty"`
	RunnerGroup        string   `json:"runnerGroup,omitempty"`
	Labels             []string `json:"labels,omitempty"`
	InputJSON          string   `json:"inputJson,omitempty"`
	DependsOnJSON      string   `json:"dependsOnJson,omitempty"`
	TriggerContextJSON string   `json:"triggerContextJson,omitempty"`
}

type AutomationRunnerJobAcceptedRequest struct {
	SessionID string `json:"sessionId"`
}

func (request AutomationRunnerJobAcceptedRequest) Input(runnerID string, jobID int64) automation.AutomationRunnerJobMutation {
	return automation.AutomationRunnerJobMutation{RunnerID: runnerID, SessionID: request.SessionID, QueueJobID: jobID}
}

type AutomationRunnerJobCompletedRequest struct {
	SessionID  string `json:"sessionId"`
	OutputJSON string `json:"outputJson"`
}

func (request AutomationRunnerJobCompletedRequest) Input(runnerID string, jobID int64) automation.AutomationRunnerJobMutation {
	return automation.AutomationRunnerJobMutation{RunnerID: runnerID, SessionID: request.SessionID, QueueJobID: jobID, OutputJSON: request.OutputJSON}
}

type AutomationRunnerJobFailedRequest struct {
	SessionID string `json:"sessionId"`
	Message   string `json:"message"`
	ErrorJSON string `json:"errorJson"`
}

func (request AutomationRunnerJobFailedRequest) Input(runnerID string, jobID int64) automation.AutomationRunnerJobMutation {
	message := request.Message
	if message == "" {
		message = request.ErrorJSON
	}
	return automation.AutomationRunnerJobMutation{RunnerID: runnerID, SessionID: request.SessionID, QueueJobID: jobID, Message: message}
}

type AutomationRunnerJobRenewRequest struct {
	SessionID    string `json:"sessionId"`
	LeaseSeconds int    `json:"leaseSeconds,omitempty"`
}

func (request AutomationRunnerJobRenewRequest) Input(runnerID string, jobID int64) automation.AutomationRunnerJobRenewMutation {
	return automation.AutomationRunnerJobRenewMutation{RunnerID: runnerID, SessionID: request.SessionID, QueueJobID: jobID, LeaseSeconds: request.LeaseSeconds}
}

type AutomationRunnerJobLease struct {
	QueueJobID int64  `json:"queueJobId"`
	LeaseOwner string `json:"leaseOwner"`
	LeaseUntil string `json:"leaseUntil,omitempty"`
}

type AutomationRunnerJobLogRequest struct {
	SessionID   string `json:"sessionId"`
	Stream      string `json:"stream"`
	Content     string `json:"content"`
	Sequence    int64  `json:"sequence"`
	SHA256      string `json:"sha256,omitempty"`
	ContentType string `json:"contentType,omitempty"`
}

func (request AutomationRunnerJobLogRequest) Input(runnerID string, jobID int64) automation.AutomationRunnerJobMutation {
	return automation.AutomationRunnerJobMutation{RunnerID: runnerID, SessionID: request.SessionID, QueueJobID: jobID, LogStream: request.Stream, LogContent: request.Content, LogSequence: request.Sequence, LogSHA256: request.SHA256, LogContentType: request.ContentType}
}

type AutomationRunnerJobArtifactRequest struct {
	SessionID     string `json:"sessionId"`
	Name          string `json:"name"`
	ContentBase64 string `json:"contentBase64"`
	Size          int64  `json:"size"`
	SHA256        string `json:"sha256"`
	ContentType   string `json:"contentType,omitempty"`
	ExpiresAt     string `json:"expiresAt,omitempty"`
	MetadataJSON  string `json:"metadataJson"`
}

func (request AutomationRunnerJobArtifactRequest) Input(runnerID string, jobID int64) automation.AutomationRunnerJobMutation {
	return automation.AutomationRunnerJobMutation{RunnerID: runnerID, SessionID: request.SessionID, QueueJobID: jobID, ArtifactName: request.Name, ArtifactSize: request.Size, ArtifactContentBase64: request.ContentBase64, ArtifactSHA256: request.SHA256, ArtifactContentType: request.ContentType, ArtifactExpiresAt: request.ExpiresAt, MetadataJSON: request.MetadataJSON}
}

type AutomationRunCancelRequest struct {
	Reason string `json:"reason"`
}

// AutomationValidationReport reports DSL validation status for a automation source snapshot.
type AutomationValidationReport struct {
	Valid  bool                        `json:"valid"`
	Errors []AutomationValidationError `json:"errors,omitempty"`
}

type AutomationValidationError struct {
	Code    string `json:"code"`
	Path    string `json:"path"`
	Message string `json:"message"`
}

func firstNonEmpty(values ...string) string {
	for _, value := range values {
		if value != "" {
			return value
		}
	}
	return ""
}

// AutomationPinnedRepo is the wire format for a pinned automation repository.
type AutomationPinnedRepo struct {
	WorkspaceID string `json:"workspaceId"`
	PrincipalID string `json:"principalId"`
	Owner       string `json:"owner"`
	Repo        string `json:"repo"`
	FullName    string `json:"fullName"`
	CreatedAt   string `json:"createdAt"`
	UpdatedAt   string `json:"updatedAt"`
}
