package dto

import "github.com/tidbcloud/AgentTeam/internal/service/actionsrunner"

// ActionsRunnerRegistrationBootstrapRequest is the GHES runner-admin bootstrap
// request sent by config.sh.
type ActionsRunnerRegistrationBootstrapRequest struct {
	URL         string `json:"url"`
	RunnerEvent string `json:"runner_event"`
}

// ActionsRunnerRegistrationBootstrap is the GHES runner-admin bootstrap
// response consumed by config.sh.
type ActionsRunnerRegistrationBootstrap struct {
	URL         string `json:"url"`
	TokenSchema string `json:"token_schema"`
	Token       string `json:"token"`
	UseV2Flow   bool   `json:"use_v2_flow"`
}

type ActionsRunnerGroupList struct {
	TotalCount   int                  `json:"total_count"`
	RunnerGroups []ActionsRunnerGroup `json:"runner_groups"`
}

type ActionsRunnerGroup struct {
	ID       int    `json:"id"`
	Name     string `json:"name"`
	Default  bool   `json:"default"`
	IsHosted bool   `json:"is_hosted"`
}

type ActionsRunnerList struct {
	TotalCount int             `json:"total_count"`
	Runners    []ActionsRunner `json:"runners"`
}

type ActionsRunner struct {
	ID     int64  `json:"id"`
	Name   string `json:"name"`
	Status string `json:"status,omitempty"`
	OS     string `json:"os,omitempty"`
}

// ActionsRunnerRegisterRequest is the runner-admin registration body sent by
// config.sh after it generates the runner RSA key pair.
type ActionsRunnerRegisterRequest struct {
	URL             string               `json:"url"`
	GroupID         int                  `json:"group_id"`
	Name            string               `json:"name"`
	Version         string               `json:"version"`
	UpdatesDisabled bool                 `json:"updates_disabled"`
	Ephemeral       bool                 `json:"ephemeral"`
	Labels          []ActionsRunnerLabel `json:"labels"`
	PublicKey       string               `json:"public_key"`
}

func (request ActionsRunnerRegisterRequest) Input() actionsrunner.RegisterRunnerInput {
	return actionsrunner.RegisterRunnerInput{Name: request.Name, PublicKey: request.PublicKey}
}

type ActionsRunnerLabel struct {
	ID   int    `json:"id"`
	Name string `json:"name"`
	Type string `json:"type"`
}

type ActionsRunnerRegisterResponse struct {
	ID            int64                      `json:"id"`
	Name          string                     `json:"name"`
	Authorization ActionsRunnerAuthorization `json:"authorization"`
}

type ActionsRunnerAuthorization struct {
	AuthorizationURL       string `json:"authorization_url"`
	LegacyAuthorizationURL string `json:"legacy_authorization_url"`
	ServerURL              string `json:"server_url"`
	ClientID               string `json:"client_id"`
}

type ActionsRunnerOAuthTokenResponse struct {
	AccessToken string `json:"access_token"`
	TokenType   string `json:"token_type"`
	ExpiresIn   int    `json:"expires_in"`
}

type ActionsRunnerBrokerSessionRequest struct {
	SessionID string             `json:"sessionId"`
	OwnerName string             `json:"ownerName"`
	Agent     ActionsRunnerAgent `json:"agent"`
}

type ActionsRunnerAgent struct {
	ID      int64  `json:"id"`
	Name    string `json:"name"`
	Version string `json:"version"`
	Status  int    `json:"status"`
}

type ActionsRunnerBrokerSessionResponse struct {
	SessionID         string `json:"sessionId"`
	OwnerName         string `json:"ownerName"`
	UseFipsEncryption bool   `json:"useFipsEncryption"`
}

type ActionsRunnerTaskAgentMessage struct {
	MessageID   int64  `json:"messageId"`
	MessageType string `json:"messageType"`
	Body        string `json:"body"`
}

func ToActionsRunnerTaskAgentMessage(message actionsrunner.TaskAgentMessage) ActionsRunnerTaskAgentMessage {
	return ActionsRunnerTaskAgentMessage{MessageID: message.MessageID, MessageType: message.MessageType, Body: message.Body}
}

type ActionsRunnerAcquireJobRequest struct {
	JobMessageID    string `json:"jobMessageId"`
	JobMessageIDAlt string `json:"job_message_id"`
}

func (request ActionsRunnerAcquireJobRequest) Input(runServiceURL string) actionsrunner.AcquireJobRequest {
	return actionsrunner.AcquireJobRequest{
		JobMessageID:  firstNonEmpty(request.JobMessageID, request.JobMessageIDAlt),
		RunServiceURL: runServiceURL,
	}
}

type ActionsRunnerRenewJobRequest struct {
	JobID    string `json:"jobId"`
	JobIDAlt string `json:"job_id"`
}

func (request ActionsRunnerRenewJobRequest) Input() actionsrunner.RenewJobRequest {
	return actionsrunner.RenewJobRequest{JobID: firstNonEmpty(request.JobID, request.JobIDAlt)}
}

type ActionsRunnerRenewJobResponse struct {
	LockedUntil string `json:"lockedUntil"`
}

type ActionsRunnerCompleteJobRequest struct {
	JobID          string           `json:"jobId"`
	JobIDAlt       string           `json:"job_id"`
	Conclusion     any              `json:"conclusion"`
	Outputs        map[string]any   `json:"outputs"`
	StepResults    []map[string]any `json:"stepResults"`
	StepResultsAlt []map[string]any `json:"step_results"`
	Annotations    []map[string]any `json:"annotations"`
	Telemetry      []map[string]any `json:"telemetry"`
}

func (request ActionsRunnerCompleteJobRequest) Input() actionsrunner.CompleteJobRequest {
	return actionsrunner.CompleteJobRequest{
		JobID:       firstNonEmpty(request.JobID, request.JobIDAlt),
		Conclusion:  request.Conclusion,
		Outputs:     request.Outputs,
		StepResults: firstNonEmptyMaps(request.StepResults, request.StepResultsAlt),
		Annotations: request.Annotations,
		Telemetry:   request.Telemetry,
	}
}

func firstNonEmptyMaps(values ...[]map[string]any) []map[string]any {
	for _, value := range values {
		if len(value) > 0 {
			return value
		}
	}
	return nil
}
