package controller

import (
	"dataservices/commons/ginparser"
	dto "dataservices/internal/dto/dataapi"
	"dataservices/internal/entity"
	service "dataservices/internal/service/central"
	"net/http"
	"strconv"

	"github.com/tidbcloud/tiinf/errs"
	tierr "github.com/tidbcloud/tiinf/errs"
	"github.com/tidbcloud/tiinf/monitor/tilog"
	"go.uber.org/zap"

	"github.com/gin-gonic/gin"
)

// Get dataapp deployment setting
// @Summary get dataapp deployment setting
// @Description get dataapp deployment setting
// @Tags dataapi
// @Param org_id   path string true "org ID"
// @Param project_id path string true "project ID"
// @Param app_id path string true "app ID"
// @Accept json
// @Produce json
// @Success 200 {object} dto.GetDataAppDeploySettingRes
// @Router /orgs/{org_id}/projects/{project_id}/apps/{app_id}/deploy/config [get]
func GetDataAppDeploySetting(c *gin.Context) {
	ctx := c.Request.Context()
	validateKeys := &[]string{ginparser.PARAM_ORG_ID, ginparser.PARAM_PROJECT_ID, ginparser.PARAM_APP_ID}
	params := ginparser.NewCommonParamsByGin(c)
	createdBy, _ := params.GetUserEmail()
	validateErr := params.ValidateUrl(validateKeys)
	if validateErr != nil {
		tilog.Error(ctx, "DS-Central-/orgs/{org_id}/projects/{project_id}/apps/{app_id}/deploy/config[get]-GetDataAppDeploySetting param validate failed!", zap.Error(validateErr), zap.String("user", createdBy))
		c.Error(validateErr)
		return
	}
	resp, err := service.GetDataAppDeploySetting(ctx, params.AppID)
	if err != nil {
		tilog.Error(ctx, "DS-Central-/orgs/{org_id}/projects/{project_id}/apps/{app_id}/deploy/config[get]-GetDataAppDeploySetting execution failed!", zap.Error(err), zap.String("user", createdBy))
		c.Error(err)
		return
	}
	resJson := &dto.GetDataAppDeploySettingRes{
		BasicRes: dto.DefaultSuccessBasicRes(),
		Data:     resp,
	}
	c.JSON(http.StatusOK, resJson)
}

// Save dataapp deployment setting godoc
// @Summary save dataapp deployment setting
// @Description save dataapp deployment setting
// @Tags dataapi
// @Param org_id   path string true "org ID"
// @Param project_id path string true "project ID"
// @Param app_id path string true "app ID"
// @Param request_body body entity.DeploymentSwithConfig true "request_body"
// @Accept json
// @Produce json
// @Success 200 {object} dto.GenericSuccessApiResponse
// @Router /orgs/{org_id}/projects/{project_id}/apps/{app_id}/deploy/config [PUT]
func SaveDataAppDeploySetting(c *gin.Context) {
	ctx := c.Request.Context()
	validateKeys := &[]string{ginparser.PARAM_ORG_ID, ginparser.PARAM_PROJECT_ID, ginparser.PARAM_APP_ID}
	params := ginparser.NewCommonParamsByGin(c)
	createdBy, _ := params.GetUserEmail()
	validateErr := params.ValidateUrl(validateKeys)
	if validateErr != nil {
		tilog.Error(ctx, "DS-Central-/orgs/{org_id}/projects/{project_id}/apps/{app_id}/deploy/config[PUT]-SaveDataAppDeploySetting param validate failed!", zap.Error(validateErr), zap.String("user", createdBy))
		c.Error(validateErr)
		return
	}

	var input entity.DeploymentSwithConfig
	err := params.BindParam(&input)
	if err != nil {
		tilog.Error(ctx, "DS-Central-/orgs/{org_id}/projects/{project_id}/apps/{app_id}/deploy/config[PUT]-SaveDataAppDeploySetting param bind failed!", zap.Error(err), zap.String("user", createdBy))
		c.Error(errs.NewBadRequest("Bind Params Failed", err))
		return
	}
	tilog.Info(ctx, "SaveDataAppDeploySetting payload", zap.Any("input", input), zap.String("user", createdBy))
	err = service.SaveDataAppDeploymentSettingSwithConfig(ctx, params.AppID, &input)
	if err != nil {
		tilog.Error(ctx, "DS-Central-/orgs/{org_id}/projects/{project_id}/apps/{app_id}/deploy/config[PUT]-SaveDataAppDeploymentSetting execution failed!", zap.Error(err), zap.Uint64("app_id", params.AppID), zap.String("user", createdBy))
		c.Error(err)
		return
	}
	c.JSON(http.StatusOK, dto.Success())
}

// Get dataapp deploy log diff
// @Summary get dataapp deploy log diff
// @Description get dataapp deploy log diff
// @Tags dataapi
// @Param org_id   path string true "org ID"
// @Param project_id path string true "project ID"
// @Param app_id path string true "app ID"
// @Param log_id query string false "log ID"
// @Param diff_type query string false "options: struct/text. default is struct"
// @Param sence query string true "options: redeploy/detail"
// @Accept json
// @Produce json
// @Success 200 {object} dto.GetDataAppDeployDiffRes
// @Router /orgs/{org_id}/projects/{project_id}/apps/{app_id}/deploy/logs/{log_id}/diff [get]
func GetDataAppDeploymentLogDiff(c *gin.Context) {
	ctx := c.Request.Context()
	validateKeys := &[]string{ginparser.PARAM_ORG_ID, ginparser.PARAM_PROJECT_ID, ginparser.PARAM_APP_ID, ginparser.PARAM_DEPLOY_LOGID}
	params := ginparser.NewCommonParamsByGin(c)
	createdBy, _ := params.GetUserEmail()
	validateErr := params.ValidateUrl(validateKeys)
	if validateErr != nil {
		tilog.Error(ctx, "DS-Central-/orgs/{org_id}/projects/{project_id}/apps/{app_id}/deploy/logs/{log_id}/diff[get]-GetDataAppDeploymentLogDiff param validate failed!", zap.Error(validateErr), zap.String("user", createdBy))
		c.Error(validateErr)
		return
	}
	diffType := c.DefaultQuery("diff_type", "struct")
	sence := c.DefaultQuery("sence", "")
	if sence == "" {
		err := errs.NewBadRequest("sence param is required", nil)
		tilog.Error(ctx, "DS-Central-/orgs/{org_id}/projects/{project_id}/apps/{app_id}/deploy/logs/{log_id}/diff[get]-GetDataAppDeploymentLogDiff sence param is required", zap.Error(err), zap.String("user", createdBy))
		c.Error(err)
		return
	}

	var (
		diff *entity.SnapshotDiff
		err  error
	)
	switch sence {
	case "detail":
		diff, err = service.GetDiffBetweenCurrDeployAndPreviousSuccDeploy(ctx, params.DeployLogID, entity.SnapshotDiffType(diffType))
	case "redeploy":
		diff, err = service.GetDiffBetweenCurrDeployAndLastestSuccDeploy(ctx, params.DeployLogID, entity.SnapshotDiffType(diffType))
	default:
		err = errs.NewBadRequest("unsupported sence: "+sence, nil)
		tilog.Error(ctx, "DS-Central-/orgs/{org_id}/projects/{project_id}/apps/{app_id}/deploy/logs/{log_id}/diff[get]-GetDataAppDeploymentLogDiff unsupported sence: "+sence, zap.Error(err), zap.String("user", createdBy))
		c.Error(err)
		return
	}
	if err != nil {
		tilog.Error(ctx, "DS-Central-/orgs/{org_id}/projects/{project_id}/apps/{app_id}/deploy/logs/{log_id}/diff[get]-GetDataAppDeploymentLogDiff execution failed", zap.Error(err), zap.String("user", createdBy))
		c.Error(tierr.NewBadRequest("failed to get deployment diff.", err))
		return
	}
	resJson := &dto.GetDataAppDeployDiffRes{
		BasicRes: dto.DefaultSuccessBasicRes(),
		Data:     diff,
	}
	c.JSON(http.StatusOK, resJson)
}

// Get dataapp deploy diff
// @Summary get dataapp deploy diff
// @Description get dataapp deploy diff
// @Tags dataapi
// @Param org_id   path string true "org ID"
// @Param project_id path string true "project ID"
// @Param app_id path string true "app ID"
// @Param diff_type query string true "struct/text"
// @Param endpoint_id query string false "endpoint ID"
// @Accept json
// @Produce json
// @Success 200 {object} dto.GetDataAppDeployDiffRes
// @Router /orgs/{org_id}/projects/{project_id}/apps/{app_id}/deploy/diff [get]
func GetDataAppDeployDiff(c *gin.Context) {
	ctx := c.Request.Context()
	validateKeys := &[]string{ginparser.PARAM_ORG_ID, ginparser.PARAM_PROJECT_ID, ginparser.PARAM_APP_ID}
	params := ginparser.NewCommonParamsByGin(c)
	createdBy, _ := params.GetUserEmail()
	validateErr := params.ValidateUrl(validateKeys)
	if validateErr != nil {
		tilog.Error(ctx, "DS-Central-/orgs/{org_id}/projects/{project_id}/apps/{app_id}/deploy/diff[get]-GetDataAppDeployDiff param validate failed!", zap.Error(validateErr), zap.String("user", createdBy))
		c.Error(validateErr)
		return
	}
	diffType := c.DefaultQuery("diff_type", "struct")
	endpointID := c.Query("endpoint_id")
	var endpointIDInt uint64
	var err error
	if endpointID != "" {
		if endpointIDInt, err = strconv.ParseUint(endpointID, 10, 64); err != nil {
			err = errs.NewBadRequest("invalid endpoint id", err)
			tilog.Error(ctx, "DS-Central-/orgs/{org_id}/projects/{project_id}/apps/{app_id}/deploy/diff[get]-GetDataAppDeployDiff invalid endpoint id", zap.Error(err), zap.String("user", createdBy))
			c.Error(err)
			return
		}
		endpointInfo, err := service.GetEndpoint(ctx, endpointIDInt)
		if err != nil {
			tilog.Error(ctx, "failed to get endpoint", zap.Error(err), zap.String("user", createdBy))
			c.Error(err)
			return
		} else if endpointInfo.DataappId != params.AppID {
			err = errs.NewNotFound("endpoint not found for the given app", nil)
			tilog.Warn(ctx, "endpoint not found for the given app", zap.String("endpoint", endpointID), zap.String("user", createdBy))
			c.Error(err)
			return
		}
	}
	diff, err := service.GetDiffBetweenEndpointAndLastestSuccDeploy(ctx, params.AppID, endpointIDInt, entity.SnapshotDiffType(diffType))
	if err != nil {
		tilog.Error(ctx, "DS-Central-/orgs/{org_id}/projects/{project_id}/apps/{app_id}/deploy/diff[get]-GetDataAppDeployDiff CompareSnapshotDiff failed", zap.Error(err), zap.String("user", createdBy))
		c.Error(tierr.NewBadRequest("CompareSnapshotDiff failed.", err))
		return
	}
	resJson := &dto.GetDataAppDeployDiffRes{
		BasicRes: dto.DefaultSuccessBasicRes(),
		Data:     diff,
	}
	c.JSON(http.StatusOK, resJson)
}

// Get deployment status (message bar)
// @Summary get deployment status (message bar)
// @Description get deployment status (message bar)
// @Tags dataapi
// @Param org_id   path string true "org ID"
// @Param project_id path string true "project ID"
// @Param app_id path string true "app ID"
// @Accept json
// @Produce json
// @Success 200 {object} dto.GetDeploymentStatus
// @Router /orgs/{org_id}/projects/{project_id}/apps/{app_id}/deploy/status [get]
func GetDataAppDeploymentStatus(c *gin.Context) {
	ctx := c.Request.Context()
	validateKeys := &[]string{ginparser.PARAM_ORG_ID, ginparser.PARAM_PROJECT_ID, ginparser.PARAM_APP_ID}
	params := ginparser.NewCommonParamsByGin(c)
	createdBy, _ := params.GetUserEmail()
	validateErr := params.ValidateUrl(validateKeys)
	if validateErr != nil {
		tilog.Error(ctx, "DS-Central-/orgs/{org_id}/projects/{project_id}/apps/{app_id}/deploy/status[get]-GetDataAppDeploymentStatus param validate failed!", zap.Error(validateErr), zap.String("user", createdBy))
		c.Error(validateErr)
		return
	}
	diff, err := service.GetDataAppDeploymentStatus(ctx, params.AppID)
	if err != nil {
		tilog.Error(ctx, "DS-Central-/orgs/{org_id}/projects/{project_id}/apps/{app_id}/deploy/status[get]-GetDataAppDeploymentStatus CompareSnapshotDiff failed", zap.Error(err), zap.String("user", createdBy))
		c.Error(tierr.NewBadRequest("CompareSnapshotDiff failed.", err))
		return
	}
	resJson := &dto.GetDeploymentStatus{
		BasicRes: dto.DefaultSuccessBasicRes(),
		Data:     diff,
	}
	c.JSON(http.StatusOK, resJson)
}

// List dataapp deploy logs
// @Summary list dataapp deploy logs
// @Description list dataapp deploy logs
// @Tags dataapi
// @Param org_id   path string true "org ID"
// @Param project_id path string true "project ID"
// @Param app_id path string true "app ID"
// @Param before query string true "before timestamp"
// @Param limit query string true "limit"
// @Accept json
// @Produce json
// @Success 200 {object} dto.ListDataAppDeployLogsRes
// @Router /orgs/{org_id}/projects/{project_id}/apps/{app_id}/deploy/logs [get]
func ListDataAppDeployLogs(c *gin.Context) {
	ctx := c.Request.Context()
	validateKeys := &[]string{ginparser.PARAM_ORG_ID, ginparser.PARAM_PROJECT_ID, ginparser.PARAM_APP_ID}
	params := ginparser.NewCommonParamsByGin(c)
	createdBy, _ := params.GetUserEmail()
	validateErr := params.ValidateUrl(validateKeys)
	if validateErr != nil {
		tilog.Error(ctx, "DS-Central-/orgs/{org_id}/projects/{project_id}/apps/{app_id}/deploy/logs[get]-ListDataAppDeployLogs param validate failed!", zap.Error(validateErr), zap.String("user", createdBy))
		c.Error(validateErr)
		return
	}
	limitStr := c.DefaultQuery("limit", "25")
	limit, limitErr := strconv.Atoi(limitStr)
	if limitErr != nil || limit > 25 {
		tilog.Error(ctx, "DS-Central-/orgs/{org_id}/projects/{project_id}/apps/{app_id}/deploy/logs[get]-ListDataAppDeployLogs failed to parse befre and limit params", zap.String("limit", limitStr), zap.Error(limitErr), zap.String("user", createdBy))
		c.Error(tierr.NewBadRequest("parse limit param failed.", nil))
		return
	}
	resp, err := service.ListDataAppDeployLogs(ctx, params.AppID, limit)
	if err != nil {
		tilog.Error(ctx, "DS-Central-/orgs/{org_id}/projects/{project_id}/apps/{app_id}/deploy/logs[get]-ListDataAppDeployLogs execution failed!", zap.Error(err), zap.String("user", createdBy))
		c.Error(err)
		return
	}
	// XXX(bing.wang) remove snapshot info in console UI.
	for _, val := range resp {
		val.Snapshot = ""
	}
	resJson := &dto.ListDataAppDeployLogsRes{
		BasicRes: dto.DefaultSuccessBasicRes(),
		Data:     resp,
	}
	c.JSON(http.StatusOK, resJson)
}

// Save deployment log name
// @Summary save deployment log name
// @Description save deployment log name
// @Tags dataapi
// @Param org_id   path string true "org ID"
// @Param project_id path string true "project ID"
// @Param app_id path string true "app ID"
// @Param log_id path string true "deployment log ID"
// @Param request_body body entity.SaveDeploymentLogParam true "request_body"
// @Accept json
// @Produce json
// @Success 200 {object} dto.GenericSuccessApiResponse
// @Router /orgs/{org_id}/projects/{project_id}/apps/{app_id}/deploy/logs/{log_id} [post]
func SaveDeploymentLog(c *gin.Context) {
	ctx := c.Request.Context()
	validateKeys := &[]string{ginparser.PARAM_ORG_ID, ginparser.PARAM_PROJECT_ID, ginparser.PARAM_APP_ID, ginparser.PARAM_DEPLOY_LOGID}
	params := ginparser.NewCommonParamsByGin(c)
	createdBy, _ := params.GetUserEmail()
	validateErr := params.ValidateUrl(validateKeys)
	if validateErr != nil {
		tilog.Error(ctx, "DS-Central-/orgs/{org_id}/projects/{project_id}/apps/{app_id}/deploy/logs/{log_id}[post]-SaveDeploymentLog param validate failed!", zap.Error(validateErr), zap.String("user", createdBy))
		c.Error(validateErr)
		return
	}

	var input entity.SaveDeploymentLogParam
	err := params.BindParam(&input)
	if err != nil {
		tilog.Error(ctx, "DS-Central-/orgs/{org_id}/projects/{project_id}/apps/{app_id}/deploy/logs/{log_id}[post]-SaveDeploymentLog param bind failed!", zap.Error(err), zap.String("user", createdBy))
		c.Error(errs.NewBadRequest("Bind Params Failed", err))
		return
	}
	tilog.Info(ctx, "SaveDeploymentLog payload", zap.Any("input", input), zap.String("user", createdBy))

	err = service.SaveDataAppDeploymentName(ctx, params.DeployLogID, input.DeployName)
	if err != nil {
		tilog.Error(ctx, "DS-Central-/orgs/{org_id}/projects/{project_id}/apps/{app_id}/deploy/logs/{log_id}[post]-SaveDataAppDeploymentName execution failed!", zap.Error(err), zap.Uint64("endpoint_id", params.EndpointID), zap.String("user", createdBy))
		c.Error(err)
		return
	}
	c.JSON(http.StatusOK, dto.Success())
}

// Deploy DataApp godoc
// @Summary deploy dataapp
// @Description deploy dataapp
// @Tags dataapi
// @Param org_id   path string true "org ID"
// @Param project_id path string true "project ID"
// @Param app_id path string true "app ID"
// @Param request_body body entity.DeployDataAppParam true "request_body"
// @Accept json
// @Produce json
// @Success 200 {object} dto.GenericSuccessApiResponse
// @Router /orgs/{org_id}/projects/{project_id}/apps/{app_id}/deploy [post]
func DeployDataApp(c *gin.Context) {
	ctx := c.Request.Context()
	validateKeys := &[]string{ginparser.PARAM_ORG_ID, ginparser.PARAM_PROJECT_ID, ginparser.PARAM_APP_ID}
	params := ginparser.NewCommonParamsByGin(c)
	createdBy, _ := params.GetUserEmail()
	validateErr := params.ValidateUrl(validateKeys)
	if validateErr != nil {
		tilog.Error(ctx, "DS-Central-/orgs/{org_id}/projects/{project_id}/apps/{app_id}/deploy[post]-DeployDataApp param validate failed!", zap.Error(validateErr), zap.String("user", createdBy))
		c.Error(validateErr)
		return
	}

	var input entity.DeployDataAppParam
	err := params.BindParam(&input)
	if err != nil {
		tilog.Error(ctx, "DS-Central-/orgs/{org_id}/projects/{project_id}/apps/{app_id}/deploy[post]-DeployDataApp param bind failed!", zap.Error(err), zap.String("user", createdBy))
		c.Error(errs.NewBadRequest("Bind Params Failed", err))
		return
	}
	tilog.Info(ctx, "DeployDataApp payload", zap.Any("input", input), zap.String("user", createdBy))

	data, err := service.TriggerDataAppDeployFromUI(ctx, params.AppID, createdBy, input.DeployName)
	if err != nil {
		tilog.Error(ctx, "DS-Central-/orgs/{org_id}/projects/{project_id}/apps/{app_id}/deploy[post]-DeployDataApp TriggerDataAppDeployFromUI failed!", zap.Error(err), zap.Uint64("endpoint_id", params.EndpointID), zap.String("user", createdBy))
		c.Error(err)
		return
	}
	resJson := &dto.DeployDataAppLogRes{
		BasicRes: dto.DefaultSuccessBasicRes(),
		Data:     data,
	}

	c.JSON(http.StatusOK, resJson)
}

// Redeploy DataApp godoc
// @Summary redeploy dataapp
// @Description redeploy dataapp
// @Tags dataapi
// @Param org_id   path string true "org ID"
// @Param project_id path string true "project ID"
// @Param app_id path string true "app ID"
// @Param request_body body entity.DeployDataAppParam true "request_body"
// @Accept json
// @Produce json
// @Success 200 {object} dto.GenericSuccessApiResponse
// @Router /orgs/{org_id}/projects/{project_id}/apps/{app_id}/deploy/logs/:log_id/deploy [post]
func RedeployDataApp(c *gin.Context) {
	ctx := c.Request.Context()
	validateKeys := &[]string{ginparser.PARAM_ORG_ID, ginparser.PARAM_PROJECT_ID, ginparser.PARAM_APP_ID, ginparser.PARAM_DEPLOY_LOGID}
	params := ginparser.NewCommonParamsByGin(c)
	createdBy, _ := params.GetUserEmail()
	validateErr := params.ValidateUrl(validateKeys)
	if validateErr != nil {
		tilog.Error(ctx, "DS-Central-/orgs/{org_id}/projects/{project_id}/apps/{app_id}/deploy/logs/:log_id/deploy[post]-RedeployDataApp param validate failed!", zap.Error(validateErr), zap.String("user", createdBy))
		c.Error(validateErr)
		return
	}

	var input entity.DeployDataAppParam
	err := params.BindParam(&input)
	if err != nil {
		tilog.Error(ctx, "DS-Central-/orgs/{org_id}/projects/{project_id}/apps/{app_id}/deploy/logs/:log_id/deploy[post]-RedeployDataApp param bind failed!", zap.Error(err), zap.String("user", createdBy))
		c.Error(errs.NewBadRequest("Bind Params Failed", err))
		return
	}
	tilog.Info(ctx, "RedeployDataApp payload", zap.Any("input", input), zap.String("user", createdBy))

	data, err := service.TriggerRedeploy(ctx, params.DeployLogID, createdBy, input.DeployName)
	if err != nil {
		tilog.Error(ctx, "DS-Central-/orgs/{org_id}/projects/{project_id}/apps/{app_id}/deploy/logs/:log_id/deploy[post]-RedeployDataApp TriggerRedeploy failed!", zap.Error(err), zap.String("user", createdBy))
		c.Error(err)
		return
	}
	resJson := &dto.DeployDataAppLogRes{
		BasicRes: dto.DefaultSuccessBasicRes(),
		Data:     data,
	}

	c.JSON(http.StatusOK, resJson)
}

// Discard DataApp godoc
// @Summary discard dataapp
// @Description discard dataapp
// @Tags dataapi
// @Param org_id   path string true "org ID"
// @Param project_id path string true "project ID"
// @Param app_id path string true "app ID"
// @Param request_body body entity.DeployDataAppParam true "request_body"
// @Accept json
// @Produce json
// @Success 200 {object} dto.GenericSuccessApiResponse
// @Router /orgs/{org_id}/projects/{project_id}/apps/{app_id}/discard [post]
func DiscardDataApp(c *gin.Context) {
	ctx := c.Request.Context()
	validateKeys := &[]string{ginparser.PARAM_ORG_ID, ginparser.PARAM_PROJECT_ID, ginparser.PARAM_APP_ID}
	params := ginparser.NewCommonParamsByGin(c)
	createdBy, _ := params.GetUserEmail()
	validateErr := params.ValidateUrl(validateKeys)
	if validateErr != nil {
		tilog.Error(ctx, "DS-Central-/orgs/{org_id}/projects/{project_id}/apps/{app_id}/discard[post]-DiscardDataApp param validate failed!", zap.Error(validateErr), zap.String("user", createdBy))
		c.Error(validateErr)
		return
	}

	err := service.DiscardDataApp(ctx, params.AppID, createdBy)
	if err != nil {
		tilog.Error(ctx, "DS-Central-/orgs/{org_id}/projects/{project_id}/apps/{app_id}/discard[post]-DiscardDataApp execution failed", zap.Error(err), zap.String("user", createdBy))
		c.Error(tierr.NewBadRequest("DiscardDataApp failed.", err))
		return
	}
	c.JSON(http.StatusOK, dto.Success())
}

// Discard Endpoint godoc
// @Summary discard endpoint
// @Description discard endpoint
// @Tags dataapi
// @Param org_id   path string true "org ID"
// @Param project_id path string true "project ID"
// @Param app_id path string true "app ID"
// @Param endpoint_id path string true "endpoint ID"
// @Param request_body body entity.DeployDataAppParam true "request_body"
// @Accept json
// @Produce json
// @Success 200 {object} dto.GenericSuccessApiResponse
// @Router /orgs/{org_id}/projects/{project_id}/apps/{app_id}/endpoints/{endpoint_id}/discard [post]
func DiscardEndpoint(c *gin.Context) {
	ctx := c.Request.Context()
	validateKeys := &[]string{ginparser.PARAM_ORG_ID, ginparser.PARAM_PROJECT_ID, ginparser.PARAM_APP_ID, ginparser.PARAM_ENDPOINT_ID}
	params := ginparser.NewCommonParamsByGin(c)
	createdBy, _ := params.GetUserEmail()
	validateErr := params.ValidateUrl(validateKeys)
	if validateErr != nil {
		tilog.Error(ctx, "DS-Central-/orgs/{org_id}/projects/{project_id}/apps/{app_id}/endpoints/{endpoint_id}/discard[post]-DiscardEndpoint param validate failed!", zap.Error(validateErr), zap.String("user", createdBy))
		c.Error(validateErr)
		return
	}

	err := service.DiscardEndpoint(ctx, params.AppID, params.EndpointID, createdBy)
	if err != nil {
		tilog.Error(ctx, "DS-Central-/orgs/{org_id}/projects/{project_id}/apps/{app_id}/endpoints/{endpoint_id}/discard[post]-DiscardEndpoint execution failed", zap.Error(err), zap.String("user", createdBy))
		c.Error(tierr.NewBadRequest("DiscardEndpoint failed.", err))
		return
	}

	c.JSON(http.StatusOK, dto.Success())
}
