package message

import (
	prometheusv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
	"github.com/tidbcloud/observability/pkg/common/constants"
	"github.com/tidbcloud/observability/pkg/common/structs"
	corev1 "k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/api/resource"
)

type CreateClusterReq struct {
	structs.ClusterBaseInfo
	// AgentAccessARN and AgentManagerARN are not needed in the 3-layers architecture
	// because the AgentEnvironment model defines account and project information
	// AgentManagerARN is a pre-defined management role created in each dataplane account for o11y
	// AgentAccessARN is a data role: o11y_{{k8s_id}}_access_role created by o11y_regional_server for each k8s
	// Compatibility solution: If agentAccessARN and agentManagerARN are passed, use o11y_management_role.
	// If not passed, use the fixed management role and generated access role.
	// Note: AgentAccessARN could be changed to agent data role arn during an in-flight request.
	AgentAccessARN string `json:"agentAccessARN" form:"agentAccessARN"`
	// AgentManagerARN is used for private link service authentication.
	AgentManagerARN string `json:"agentManagerARN" form:"agentManagerARN"`
	// AgentAccessAccount is used for agent access account, if not set, use agentAccessARN, if set, use agentAccessAccount and agentAccessARN must not set
	AgentAccessAccount string `json:"agentAccessAccount" form:"agentAccessAccount"`
	//AgentNextGen is used for next gen agent, if not set, use old path
	AgentNextGen bool `json:"agentNextGen" form:"agentNextGen"`

	// agent config template, now not used
	AgentTemplateName string `json:"agentTemplateName" form:"agentTemplateName"`

	// only for shared-vpc
	AgentSharedRole bool `json:"agentSharedRole" form:"agentSharedRole"`

	// only prometheus spec(vmalert use this, wrong ways)
	MonitorSpecID string `json:"monitorSpecID" form:"monitorSpecID"`

	MonitorPromRules prometheusv1.PrometheusRuleSpec `json:"monitorPromRules" form:"monitorPromRules" swaggertype:"object"`
	RuleTemplateID   string                          `json:"ruleTemplateID" form:"ruleTemplateID"`
	MuteAlert        bool                            `json:"muteAlert" form:"muteAlert"`

	ParentClusterID string `json:"parentClusterID" form:"parentClusterID"`
	KeySpaceID      string `json:"keySpaceID" form:"keySpaceID"`

	// describe agent deployment env, e.g VPC, account and provider
	//if not set, use Compatibility path
	AgentEnvironment *structs.AgentEnvironment `json:"agentEnvironment,omitempty" form:"agentEnvironment,omitempty"`
	// tidb cluster or other observed component information, for o11y auto scale
	Observed structs.Observed `json:"observed" form:"observed"`

	// o11y provided data categories, such as monitoring, logging, topsql, etc.
	// The default value is []string{"metrics", "logs"}, which will be added to the cluster's CR.
	// If topsql is enabled, add "topsql" to it.
	Category []string `json:"category" form:"category"`

	// A temporary parameter set specifically for the k8s-infra cluster.
	// The purpose is to specify which seed cluster k8s-infra will push the metrics to.
	// This parameter should be deleted in the future when k8s-infra metrics are pushed to its own cluster
	SeedClusterID string `json:"seedClusterID" form:"seedClusterID"`

	// BYOCVPCPeering carries dataplane-specific peering info used by the regional
	// server to ensure routes in the statically provisioned o11y VPC.
	BYOCVPCPeering *BYOCVPCPeering `json:"byocVpcPeering,omitempty" form:"byocVpcPeering"`
}

type BYOCVPCPeering struct {
	PeeringConnectionID string `json:"peeringConnectionID" form:"peeringConnectionID"`
	DataplaneVPCCIDR    string `json:"dataplaneVpcCIDR" form:"dataplaneVpcCIDR"`
}

type CreateClusterResp struct {
	structs.ObservabilityCluster
}

type UpdateClusterReq struct {
	structs.CommonReqInfo
	ID             string `json:"id" swaggerignore:"true"`
	MuteAlert      *bool  `json:"muteAlert" form:"muteAlert"`
	RuleTemplateID string `json:"ruleTemplateID" form:"ruleTemplateID"`
	MonitorSpecID  string `json:"monitorSpecID" form:"monitorSpecID"`
}

type UpdateClusterResp struct {
	structs.ClusterBaseInfo
}

type DeleteClusterReq struct {
	structs.CommonReqInfo
	ID             string `json:"id" swaggerignore:"true"`
	BizType        string `json:"bizType" form:"bizType"`
	AgentAccessARN string `json:"agentAccessARN" form:"agentAccessARN"`
}

type DeleteClusterResp struct {
	structs.ClusterBaseInfo
}

type PauseClusterReq struct {
	structs.CommonReqInfo
	ID string `json:"id" swaggerignore:"true"`
}

type PauseClusterResp struct {
	structs.ClusterBaseInfo
}

type ResumeClusterReq struct {
	structs.CommonReqInfo
	ID string `json:"id" swaggerignore:"true"`
}

type ResumeClusterResp struct {
	structs.ClusterBaseInfo
}

type QueryClustersReq struct {
	structs.CommonReqInfo
	TenantID      string `json:"tenantID" form:"tenantID"`
	ProjectID     string `json:"projectID" form:"projectID"`
	ApplicationID string `json:"applicationID" form:"applicationID"`
	BizType       string `json:"bizType" form:"bizType"`
	ShowDeleted   bool   `json:"showDeleted" form:"showDeleted"`
	ContinueRequest
}

type QueryClustersResp struct {
	Clusters []structs.ClusterBaseInfo `json:"clusters"`
	Parital  bool                      `json:"partial"`
	ContinueResponse
}

type ClusterWithStorageInfo struct {
	structs.ClusterBaseInfo
	StorageInfo         []structs.StorageInfo `json:"storageInfo,omitempty"`
	LogQueryUri         string                `json:"logQueryUri,omitempty"`
	// MultitenantQueryUri is an API v1 base URI that already includes encoded query parameters such as extra_filters[].
	MultitenantQueryUri string                `json:"multitenantQueryUri,omitempty"`
	DiagnosisQueryUri   string                `json:"diagnosisQueryUri,omitempty"`
}

type QueryClustersWithStorageResp struct {
	Clusters []ClusterWithStorageInfo `json:"clusters"`
	Partial  bool                     `json:"partial"`
	ContinueResponse
}

type ListClustersWithMetadataReq struct {
	TenantIds  string `json:"tenantIds" form:"tenantIds"`
	ProjectIds string `json:"projectIds" form:"projectIds"`
	ClusterIds string `json:"clusterIds" form:"clusterIds"`
	Env        string `json:"env" form:"env"`
	ShowInfra  bool   `json:"showInfra" form:"showInfra"`
}

// ClusterWithInfra extends ClusterBaseInfo with nextgen-specific IDs and optional
// infra-cluster rows (populated only when showInfra=true).
type ClusterWithInfra struct {
	structs.ClusterBaseInfo
	DataplaneID   string                    `json:"dataplaneId,omitempty"`
	SharedPoolID  string                    `json:"sharedPoolId,omitempty"`
	InfraClusters []structs.ClusterBaseInfo `json:"infraClusters,omitempty"`
}

// ListClustersWithMetadataResp is the response envelope for the v2 cluster-list
// endpoint. It is a superset of QueryClustersResp and is safe to use as a drop-in
// replacement (same JSON keys, additional fields use omitempty).
type ListClustersWithMetadataResp struct {
	Clusters []ClusterWithInfra `json:"clusters"`
	Partial  bool               `json:"partial"`
}

type DetailClusterReq struct {
	structs.CommonReqInfo
	ID      string `json:"id" swaggerignore:"true"`
	BizType string `json:"bizType" form:"bizType"`
}

type DetailClusterResp struct {
	structs.ObservabilityCluster
}

type ModifyMonitorSpecReq struct {
	structs.CommonReqInfo
	ID     string `json:"id" swaggerignore:"true"`
	SpecID string `json:"specID" validate:"required"`
}

type ModifyMonitorSpecResp struct {
}

type ModifyAgentObservedReq struct {
	structs.CommonReqInfo
	ID       string           `json:"id" swaggerignore:"true"`
	Observed structs.Observed `json:"observed" validate:"required"`
}
type ModifyAgentObservedResp struct {
}

type PauseReconcileReq struct {
	structs.CommonReqInfo
	ID           string `json:"id" swaggerignore:"true"`
	PauseCluster bool   `json:"pauseCluster" form:"pauseCluster"`
}

type ModifyMonitorModeReq struct {
	structs.CommonReqInfo
	ID        string              `json:"id" swaggerignore:"true"`
	ShareMode constants.ShareMode `json:"shareMode" validate:"required"`
}

type ModifyMonitorModeResp struct {
}

type ModifyMonitorStorageReq struct {
	structs.CommonReqInfo
	ID        string            `json:"id" swaggerignore:"true"`
	Namespace string            `json:"namespace"`
	PVCName   string            `json:"PVCName"`
	Request   resource.Quantity `json:"request" swaggertype:"string"`
}

type ModifyMonitorStorageResp struct {
}

type ModifyMonitorResourceReq struct {
	structs.CommonReqInfo
	ID           string                               `json:"id" swaggerignore:"true"`
	ResourceType corev1.ResourceName                  `json:"resourceType" swaggertype:"string"`
	ResourceMeta map[corev1.ResourceName]ResourceMeta `json:"resourceMeta"`
}

type ResourceMeta struct {
	Namespace string            `json:"namespace"`
	PVCName   string            `json:"PVCName"`
	Request   resource.Quantity `json:"request" swaggertype:"string"`
	SpecID    string            `json:"specID"`
}

type ModifyMonitorResourceResp struct {
}

type GetMonitorResourceReq struct {
	structs.CommonReqInfo
	ID string `json:"id" swaggerignore:"true"`
	//PVCName   string            `json:"PVCName"`
}

type GetMonitorResourceResp struct {
	Requests corev1.ResourceList `json:"requests" swaggerignore:"true"`
}

type UpdateAlertRulesReq struct {
	structs.CommonReqInfo
	ID               string                          `json:"id" swaggerignore:"true"`
	MonitorPromRules prometheusv1.PrometheusRuleSpec `json:"monitorPromRules" form:"monitorPromRules" validate:"required" swaggertype:"object"`
	Override         bool                            `json:"override" form:"override"` //false:add , true:replace
	BizType          string                          `json:"bizType" form:"bizType"`
	ShareMode        constants.ShareMode             `json:"shareMode" form:"shareMode"`
}

type UpdateAlertRulesResp struct {
}

type QueryAlertRulesReq struct {
	structs.CommonReqInfo
	BizType       string `swaggerignore:"true" json:"bizType" validate:"required,max=32"`
	TenantID      string `swaggerignore:"true" json:"tenantID" form:"tenantID" validate:"required,max=20"`
	ProjectID     string `swaggerignore:"true" json:"projectID" form:"projectID" validate:"max=20"`
	ApplicationID string `swaggerignore:"true" json:"applicationID" form:"applicationID" validate:"required,max=32"`
}

type QueryAlertRulesResp struct {
	MonitorPromRules prometheusv1.PrometheusRuleSpec `json:"monitorPromRules" form:"monitorPromRules" swaggertype:"object"`
}

type UpdateAlertRulesByCloudUserReq struct {
	structs.CommonReqInfo
	BizType       string                           `swaggerignore:"true" json:"bizType" validate:"required,max=32"`
	TenantID      string                           `swaggerignore:"true" json:"tenantID" form:"tenantID" validate:"required,max=20"`
	ProjectID     string                           `swaggerignore:"true" json:"projectID" form:"projectID" validate:"max=20"`
	ApplicationID string                           `swaggerignore:"true" json:"applicationID" form:"applicationID" validate:"required,max=32"`
	AlertRules    map[string]structs.AlertRuleBase `json:"alertRules" form:"alertRules"`
}
type UpdateAlertRulesByCloudUserResp struct {
	Data map[string]structs.UpdateAlertRule `json:"data"`
}

type QueryAlertRulesByCloudUserResp struct {
	AlertRuleList []structs.AlertRuleGroup `json:"alertRuleList" form:"alertRuleList"`
}

type ModifyAlertRulesTemplateReq struct {
	structs.CommonReqInfo
	TemplateID       string                          `json:"templateID" form:"templateID" validate:"required"`
	MonitorPromRules prometheusv1.PrometheusRuleSpec `json:"monitorPromRules" form:"monitorPromRules" validate:"required" swaggertype:"object"`
}

type ApplyLogAlertRulesReq struct {
	structs.CommonReqInfo
	RulesConfig prometheusv1.PrometheusRuleSpec `json:"rulesConfig" form:"rulesConfig" validate:"required" swaggertype:"object"`
}

type ModifyAlertRulesTemplateResp struct {
}

type DeleteAlertRulesTemplateReq struct {
	structs.CommonReqInfo
	ID string `json:"id" from:"id" validate:"required"`
}

type DeleteAlertRulesTemplateResp struct {
	MonitorPromRules prometheusv1.PrometheusRuleSpec `json:"monitorPromRules" form:"monitorPromRules" validate:"required" swaggertype:"object"`
}

type QueryAlertRulesTemplateReq struct {
	structs.CommonReqInfo
	ID string `json:"id" swaggerignore:"true"`
}

type QueryAlertRulesTemplateResp struct {
	MonitorPromRules prometheusv1.PrometheusRuleSpec `json:"monitorPromRules" form:"monitorPromRules" validate:"required" swaggertype:"object"`
}

type GetClusterExternalReq struct {
	BizType       string `swaggerignore:"true" json:"bizType" validate:"required,max=32"`
	TenantID      string `swaggerignore:"true" json:"tenantID" form:"tenantID" validate:"required,max=20"`
	ProjectID     string `swaggerignore:"true" json:"projectID" form:"projectID" validate:"max=20"`
	ApplicationID string `swaggerignore:"true" json:"applicationID" form:"applicationID" validate:"required,max=63"`
}

type GetByocObservabilityVcpuReq struct {
	Start string `json:"start" form:"start" binding:"required"`
	End   string `json:"end" form:"end" binding:"required"`
	Step  string `json:"step" form:"step"`
}

type GetClusterExternalResp struct {
	ID            string                       `json:"id"`
	Vendor        constants.ProvidedVendor     `json:"vendor"`
	Region        string                       `json:"region"`
	BizType       string                       `json:"bizType"`
	TenantID      string                       `json:"tenantID"`
	ProjectID     string                       `json:"projectID"`
	ApplicationID string                       `json:"applicationID"`
	Metrics       *ExternalMetricsConfig       `json:"metrics,omitempty"`
	Logs          *ExternalLogsConfig          `json:"logs,omitempty"`
	SlowQuery     *ExternalSlowQueryConfig     `json:"slowQuery,omitempty"`
	KeyVisual     *ExternalKeyVisualConfig     `json:"keyVisual,omitempty"`
	Alerts        *ExternalAlertConfig         `json:"alerts,omitempty"`
	SqlStatements *ExternalSqlStatementsConfig `json:"sqlStatements,omitempty"`
}

type ExternalMetricsConfig struct {
	OpenReadUri string `json:"openReadUri" form:"openReadUri"`
}

type ExternalLogsConfig struct {
	OpenReadUri string `json:"openReadUri" form:"openReadUri"`
}

type ExternalSlowQueryConfig struct {
	OpenReadUri string `json:"openReadUri" form:"openReadUri"`
}

type ExternalSqlStatementsConfig struct {
	OpenReadUri string `json:"openReadUri" form:"openReadUri"`
}

type ExternalAlertConfig struct {
	RuleTemplateID string `json:"ruleTemplateID"`
}

type ExternalKeyVisualConfig struct {
	OpenReadUri string `json:"openReadUri" form:"openReadUri"`
}
