package cluster

import (
	"time"

	"github.com/tidbcloud/devops/api"
)

type TrafficReplay struct {
	ReplayID              string                      `json:"replay_id"`
	OrgID                 string                      `json:"org_id"`
	ProjectID             string                      `json:"project_id"`
	ClusterID             string                      `json:"cluster_id"`
	DesiredState          string                      `json:"desired_state"`
	CurrentState          string                      `json:"current_state"`
	SourceClusterID       string                      `json:"source_cluster_id"`
	CloudProvider         string                      `json:"cloud_provider"`
	Region                string                      `json:"region"`
	ReplayTasks           []*TrafficReplayTask        `json:"replay_tasks"`
	ReplayConfig          *TrafficReplayCommonConfig  `json:"replay_config"`
	Replicas              int32                       `json:"replicas"`
	TaskResources         *TrafficReplayTaskResources `json:"task_resources"`
	ReplayImage           string                      `json:"replay_image"`
	SourceAuditCredential *TrafficReplayAuditLogAddr  `json:"source_audit_credential"`
	ReplayStatus          *TrafficReplayStatus        `json:"replay_status"`
	CreatedAt             time.Time                   `json:"created_at"`
	UpdatedAt             time.Time                   `json:"updated_at"`
}

type TrafficReplayCommonConfig struct {
	ReplayConfig *TrafficReplayConfig `json:"replay_config"`
	Username     string               `json:"username"`
	Password     string               `json:"password"`
}

type TrafficReplayConfig struct {
	ReplayStartTime string            `json:"replay_start_time"`
	RunStartTime    string            `json:"run_start_time"`
	ReplayIndex     int32             `json:"replay_index"`
	CustomArguments map[string]string `json:"custom_arguments"`
	Format          string            `json:"format"`
	IgnoreErrs      bool              `json:"ignore_errs"`
	PsClose         string            `json:"ps_close"`
	BufSize         int32             `json:"buf_size"`
	Speed           string            `json:"speed"`
	DynamicInput    bool              `json:"dynamic_input"`
	ReadOnly        bool              `json:"read_only"`
}

type TrafficReplayTaskResources struct {
	InstanceType string `json:"instance_type"`
	StorageSize  string `json:"storage_size"`
}

type TrafficReplayTask struct {
	Name             string                      `json:"name"`
	DataSource       *TrafficReplayDataSource    `json:"data_source"`
	DataTarget       *TrafficReplayDataTarget    `json:"data_target"`
	Replicas         int32                       `json:"replicas"`
	ReplayStartTime  string                      `json:"replay_start_time"`
	RunStartTime     string                      `json:"run_start_time"`
	Resources        *TrafficReplayTaskResources `json:"resources"`
	PerReplayConfigs []*TrafficReplayConfig      `json:"per_replay_configs"`
	Image            string                      `json:"image"`
}

type TrafficReplayDataSource struct {
	SourceAuditLogAddrs []*TrafficReplayAuditLogAddr `json:"source_audit_log_addrs"`
}

type TrafficReplayDataTarget struct {
	Endpoint string `json:"endpoint"`
	Username string `json:"username"`
	Password string `json:"password"`
}

type TrafficReplayAuditLogAddr struct {
	AWS    *TrafficReplayAWSAuditLog    `json:"aws,omitempty"`
	GCP    *TrafficReplayGCPAuditLog    `json:"gcp,omitempty"`
	Aliyun *TrafficReplayAliyunAuditLog `json:"aliyun,omitempty"`
}

type TrafficReplayAliyunAuditLog struct {
	BucketURL       string `json:"bucket_url,omitempty"`
	AccessKeyID     string `json:"access_key_id,omitempty"`
	SecretAccessKey string `json:"secret_access_key,omitempty"`
}

type TrafficReplayAWSAuditLog struct {
	S3Url      string `json:"s3_url"`
	RoleArn    string `json:"role_arn"`
	ExternalID string `json:"external_id"`
}

type TrafficReplayGCPAuditLog struct {
	GcsUrl             string `json:"gcs_url"`
	ServiceAccountJson string `json:"service_account_json"`
}

type TrafficReplayStatus struct {
	Phase          string                     `json:"phase"`
	Message        string                     `json:"message"`
	Tasks          []*TrafficReplayTaskStatus `json:"tasks"`
	LastUpdateTime time.Time                  `json:"last_update_time"`
	AwsNodeRoleArn string                     `json:"aws_node_role_arn"`
}

type TrafficReplayTaskStatus struct {
	Name            string                        `json:"name"`
	ReplicaStatuses []*TrafficReplayReplicaStatus `json:"replica_statuses"`
	Message         string                        `json:"message"`
}

type TrafficReplayReplicaStatus struct {
	PodName  string                 `json:"pod_name"`
	Index    int32                  `json:"index"`
	Phase    string                 `json:"phase"`
	Ready    bool                   `json:"ready"`
	Message  string                 `json:"message"`
	TaskInfo *TrafficReplayTaskInfo `json:"task_info"`
}

type TrafficReplayTaskInfo struct {
	Type                 string                       `json:"type"`
	Status               string                       `json:"status"`
	StartTime            string                       `json:"start_time"`
	EndTime              string                       `json:"end_time"`
	Progress             int32                        `json:"progress"`
	Error                string                       `json:"error"`
	LastCommandTimestamp string                       `json:"last_command_timestamp"`
	SyncTime             string                       `json:"sync_time"`
	SourceAuditLogAddrs  []*TrafficReplayAuditLogAddr `json:"source_audit_log_addrs"`
	TotalCommands        int64                        `json:"total_commands"`
}

type TrafficReplaySpec struct {
	SourceClusterID       string                      `json:"source_cluster_id,omitempty"`
	TargetClusterID       string                      `json:"target_cluster_id,omitempty"`
	ProjectID             string                      `json:"project_id,omitempty"`
	DatabaseUsername      string                      `json:"database_username,omitempty"`
	DatabasePassword      string                      `json:"database_password,omitempty"`
	ConfigReplayStartTime string                      `json:"config_replay_start_time,omitempty"`
	ConfigRunStartTime    string                      `json:"config_run_start_time,omitempty"`
	ConfigCustomArguments map[string]string           `json:"config_custom_arguments,omitempty"`
	Replicas              int32                       `json:"replicas,omitempty"`
	ReplayImage           string                      `json:"replay_image,omitempty"`
	CloudProvider         string                      `json:"cloud_provider,omitempty"`
	Region                string                      `json:"region,omitempty"`
	TaskResource          *TrafficReplayTaskResources `json:"task_resources,omitempty"`
	SourceAuditCredential *TrafficReplayAuditLogAddr  `json:"source_audit_credential,omitempty"`

	ReplayTasks string `json:"replay_tasks,omitempty"` // JSON encoded array of task
}

type ListTrafficReplaysRequest struct {
	api.PaginationReq

	TenantID  string `form:"tenant_id" binding:"required"`
	ClusterID string `form:"cluster_id" binding:"required"`
}

type ListTrafficReplaysResponse struct {
	api.BaseResp

	Replays []*TrafficReplay `json:"items"`
	Total   int64            `json:"total"`
}

type GetTrafficReplayRequest struct {
	TenantID  string `form:"tenant_id" binding:"required"`
	ClusterID string `form:"cluster_id" binding:"required"`
}

type GetTrafficReplayResponse struct {
	api.BaseResp

	Replay *TrafficReplay `json:"replay"`
}

type CreateTrafficReplayRequest struct {
	TenantID   string             `json:"tenant_id" binding:"required"`
	ClusterID  string             `json:"cluster_id" binding:"required"`
	ReplaySpec *TrafficReplaySpec `json:"replay_spec" binding:"required"`
}

type CreateTrafficReplayResponse struct {
	api.BaseResp

	InstanceID uint64 `json:"instance_id"`
}

type UpdateTrafficReplayRequest struct {
	TenantID          string             `json:"tenant_id" binding:"required"`
	ClusterID         string             `json:"cluster_id" binding:"required"`
	ReplaySpec        *TrafficReplaySpec `json:"replay_spec" binding:"required"`
	ChangedReplaySpec string             `json:"changed_replay_spec"`
}

type UpdateTrafficReplayResponse struct {
	api.BaseResp

	InstanceID uint64 `json:"instance_id"`
}

type DeleteTrafficReplayRequest struct {
	TenantID  string `form:"tenant_id" binding:"required"`
	ClusterID string `form:"cluster_id" binding:"required"`
}

type DeleteTrafficReplayResponse struct {
	api.BaseResp

	InstanceID uint64 `json:"instance_id"`
}

type StartTrafficReplayRequest struct {
	TenantID  string `json:"tenant_id" binding:"required"`
	ClusterID string `json:"cluster_id" binding:"required"`
}

type StartTrafficReplayResponse struct {
	api.BaseResp

	InstanceID uint64 `json:"instance_id"`
}

type StopTrafficReplayRequest struct {
	TenantID  string `json:"tenant_id" binding:"required"`
	ClusterID string `json:"cluster_id" binding:"required"`
}

type StopTrafficReplayResponse struct {
	api.BaseResp

	InstanceID uint64 `json:"instance_id"`
}
