package tidbtools

import (
	"github.com/gin-gonic/gin"
	"github.com/tidbcloud/devops/api"
	toolsdto "github.com/tidbcloud/devops/api/tidbtools"
	ctrl "github.com/tidbcloud/devops/pkg/controller"
)

// ListBackups
//
//	@Id				TidbToolsControllerListBackups
//	@Description	list Dedicated or Premium cluster backups
//	@Tags			TidbToolsController
//	@Accept			json
//	@Produce		json
//	@Param			cluster_id	path		string	true	"cluster id"
//	@Param			page		query		int		false	"page, default 1"
//	@Param			page_size	query		int		false	"page size, default 20, max 200 for Dedicated and max 100 for Premium"
//	@Success		200			{object}	tidbtools.ListBackupsResp
//	@Failure		default		{object}	api.BaseResp
//	@Router			/api/v1/devops/{cluster_id}/tidbtools/backups [get]
func (c *TidbToolsController) ListBackups(ctx *gin.Context) {
	clusterID, ci, ok := c.requireClusterAccess(ctx)
	if !ok {
		return
	}
	if !supportsBackupRestore(ci.clusterType, ci.servicePlan) {
		c.notImplemented(ctx, "ListBackups")
		return
	}
	page, pageSize, err := parsePaging(ctx)
	if err != nil {
		ctrl.FailWithCode(ctx, err, api.ErrCodeInvalidArgument)
		return
	}
	if ci.clusterType == logicalType {
		if err := validatePremiumBackupPageSize(pageSize); err != nil {
			ctrl.FailWithCode(ctx, err, api.ErrCodeInvalidArgument)
			return
		}
		resp, listErr := c.svc.ListPremiumBackups(ctx, ci.orgID, ci.projectID, clusterID, page, pageSize)
		if listErr != nil {
			ctrl.Fail(ctx, listErr)
			return
		}
		ctrl.Success(ctx, toolsdto.ToListPremiumBackupsResp(resp))
		return
	}
	resp, err := c.svc.ListBackups(ctx, ci.orgID, ci.projectID, clusterID, uint32(page), uint32(pageSize))
	if err != nil {
		ctrl.Fail(ctx, err)
		return
	}
	ctrl.Success(ctx, toolsdto.ToListBackupsResp(resp))
}

// ListLogBackups
//
//	@Id				TidbToolsControllerListLogBackups
//	@Description	list Dedicated log backups
//	@Tags			TidbToolsController
//	@Accept			json
//	@Produce		json
//	@Param			cluster_id	path		string	true	"cluster id"
//	@Param			page		query		int		false	"page, default 1"
//	@Param			page_size	query		int		false	"page size, default 20, max 200"
//	@Success		200			{object}	tidbtools.ListLogBackupsResp
//	@Failure		default		{object}	api.BaseResp
//	@Router			/api/v1/devops/{cluster_id}/tidbtools/log-backups [get]
func (c *TidbToolsController) ListLogBackups(ctx *gin.Context) {
	clusterID, ci, ok := c.requireClusterAccess(ctx)
	if !ok {
		return
	}
	if ci.clusterType != dedicatedType {
		c.notImplemented(ctx, "ListLogBackups")
		return
	}
	page, pageSize, err := parsePaging(ctx)
	if err != nil {
		ctrl.FailWithCode(ctx, err, api.ErrCodeInvalidArgument)
		return
	}
	resp, err := c.svc.ListLogBackups(ctx, ci.orgID, ci.projectID, clusterID, uint32(page), uint32(pageSize))
	if err != nil {
		ctrl.Fail(ctx, err)
		return
	}
	ctrl.Success(ctx, toolsdto.ToListLogBackupsResp(resp))
}

// GetBackupSetting
//
//	@Id				TidbToolsControllerGetBackupSetting
//	@Description	get Dedicated backup setting
//	@Tags			TidbToolsController
//	@Accept			json
//	@Produce		json
//	@Param			cluster_id	path		string	true	"cluster id"
//	@Success		200			{object}	tidbtools.DedicatedBackupSetting
//	@Failure		default		{object}	api.BaseResp
//	@Router			/api/v1/devops/{cluster_id}/tidbtools/backup-setting [get]
func (c *TidbToolsController) GetBackupSetting(ctx *gin.Context) {
	clusterID, ci, ok := c.requireClusterAccess(ctx)
	if !ok {
		return
	}
	if ci.clusterType != dedicatedType {
		c.notImplemented(ctx, "GetBackupSetting")
		return
	}
	resp, err := c.svc.GetBackupSetting(ctx, ci.orgID, ci.projectID, clusterID)
	if err != nil {
		ctrl.Fail(ctx, err)
		return
	}
	ctrl.Success(ctx, toolsdto.ToGetBackupSettingResp(resp))
}

// GetNextGenBackupSetting returns backup settings for Premium and Essential v2 clusters.
//
//	@Id				TidbToolsControllerGetNextGenBackupSetting
//	@Description	get Premium or Essential v2 backup setting
//	@Tags			TidbToolsController
//	@Accept			json
//	@Produce		json
//	@Param			cluster_id	path		string	true	"cluster id"
//	@Success		200			{object}	tidbtools.NextGenBackupSetting
//	@Failure		default		{object}	api.BaseResp
//	@Router			/api/v1/devops/{cluster_id}/tidbtools/nextgen-backup-setting [get]
func (c *TidbToolsController) GetNextGenBackupSetting(ctx *gin.Context) {
	clusterID, ci, ok := c.requireClusterAccess(ctx)
	if !ok {
		return
	}
	if ci.clusterType != logicalType || !supportsBackupRestore(ci.clusterType, ci.servicePlan) {
		c.notImplemented(ctx, "GetNextGenBackupSetting")
		return
	}
	setting, policies, err := c.svc.GetPremiumBackupSetting(ctx, ci.orgID, ci.projectID, clusterID)
	if err != nil {
		ctrl.Fail(ctx, err)
		return
	}
	ctrl.Success(ctx, toolsdto.ToGetNextGenBackupSettingResp(setting, policies))
}

// ListBackupExports
//
//	@Id				TidbToolsControllerListBackupExports
//	@Description	list Dedicated backup export jobs
//	@Tags			TidbToolsController
//	@Accept			json
//	@Produce		json
//	@Param			cluster_id	path		string	true	"cluster id"
//	@Param			page		query		int		false	"page, default 1"
//	@Param			page_size	query		int		false	"page size, default 20, max 200"
//	@Success		200			{object}	tidbtools.ListBackupExportsResp
//	@Failure		default		{object}	api.BaseResp
//	@Router			/api/v1/devops/{cluster_id}/tidbtools/backup-exports [get]
func (c *TidbToolsController) ListBackupExports(ctx *gin.Context) {
	clusterID, ci, ok := c.requireClusterAccess(ctx)
	if !ok {
		return
	}
	if ci.clusterType != dedicatedType {
		c.notImplemented(ctx, "ListBackupExports")
		return
	}
	page, pageSize, err := parsePaging(ctx)
	if err != nil {
		ctrl.FailWithCode(ctx, err, api.ErrCodeInvalidArgument)
		return
	}
	resp, err := c.svc.ListBackupExports(ctx, ci.orgID, ci.projectID, clusterID, uint32(page), uint32(pageSize))
	if err != nil {
		ctrl.Fail(ctx, err)
		return
	}
	ctrl.Success(ctx, toolsdto.ToListBackupExportsResp(resp))
}

// ListExports
//
//	@Id				TidbToolsControllerListExports
//	@Description	list Premium or Essential v2 data export tasks
//	@Tags			TidbToolsController
//	@Accept			json
//	@Produce		json
//	@Param			cluster_id	path		string	true	"cluster id"
//	@Param			page		query		int		false	"page, default 1"
//	@Param			page_size	query		int		false	"page size, default 20, max 200"
//	@Success		200			{object}	tidbtools.ListExportsResp
//	@Failure		default		{object}	api.BaseResp
//	@Router			/api/v1/devops/{cluster_id}/tidbtools/exports [get]
func (c *TidbToolsController) ListExports(ctx *gin.Context) {
	clusterID, ci, ok := c.requireClusterAccess(ctx)
	if !ok {
		return
	}
	if !supportsBackupRestore(ci.clusterType, ci.servicePlan) || ci.clusterType != logicalType {
		c.notImplemented(ctx, "ListExports")
		return
	}
	page, pageSize, err := parsePaging(ctx)
	if err != nil {
		ctrl.FailWithCode(ctx, err, api.ErrCodeInvalidArgument)
		return
	}
	resp, err := c.svc.ListPremiumExports(ctx, ci.orgID, ci.projectID, clusterID, page, pageSize)
	if err != nil {
		ctrl.Fail(ctx, err)
		return
	}
	ctrl.Success(ctx, toolsdto.ToListPremiumExportsResp(resp))
}
