package export_svc

import (
	"context"
	"strings"

	"github.com/tidbcloud/serverless-service/idl/pbgen/proto/console"
	"github.com/tidbcloud/serverless-service/internal/domain/constant"
	"github.com/tidbcloud/serverless-service/internal/domain/vo"
	"github.com/tidbcloud/serverless-service/internal/service/console_auditlog"
	"github.com/tidbcloud/serverless-service/internal/utils"
	"github.com/tidbcloud/tiinf/sdk/auditlog"
)

func recordCreateExportAuditLog(
	ctx context.Context,
	req *console.CreateExportRequest,
	exportVo *vo.Export,
	err error,
) {
	eventType := exportTargetEvent(req.GetTarget().GetType())
	details := buildExportDetails(req.GetDisplayName(), exportVo)
	console_auditlog.SubmitWithStringIDs(
		ctx,
		eventType,
		req.GetOrgId(),
		req.GetProjectId(),
		req.GetClusterId(),
		details,
		err,
	)
}

func recordExportIDAuditLog(
	ctx context.Context,
	event auditlog.EventType,
	reqOrgID, reqProjectID, clusterID, exportID string,
	displayName string,
	err error,
) {
	details := auditlog.Details{
		auditlog.KeyExportID: exportID,
	}
	if displayName != "" {
		details[auditlog.KeyDisplayName] = displayName
	}
	console_auditlog.SubmitWithStringIDs(ctx, event, reqOrgID, reqProjectID, clusterID, details, err)
}

func exportTargetEvent(targetType console.ExportTargetType_Enum) auditlog.EventType {
	switch targetType {
	case console.ExportTargetType_S3:
		return auditlog.EventExportDataToAWS
	case console.ExportTargetType_GCS:
		return auditlog.EventExportDataToGCP
	case console.ExportTargetType_AZURE_BLOB:
		return auditlog.EventExportDataToAzure
	case console.ExportTargetType_OSS:
		return auditlog.EventExportDataToAlibabaCloud
	default:
		return auditlog.EventExportDataToLocal
	}
}

func buildExportDetails(displayName string, exportVo *vo.Export) auditlog.Details {
	details := auditlog.Details{}
	if displayName != "" {
		details[auditlog.KeyDisplayName] = displayName
	}
	if exportVo == nil {
		return details
	}
	if exportVo.ID != "" {
		details[auditlog.KeyExportID] = exportVo.ID
	}
	if exportVo.DisplayName != "" {
		details[auditlog.KeyDisplayName] = exportVo.DisplayName
	}
	if exportVo.FileType != "" {
		details[auditlog.KeyDataFormat] = string(exportVo.FileType)
	}
	switch exportVo.TargetType {
	case constant.ExportTargetTypeS3:
		details[auditlog.KeyBucketUri] = utils.RedactSourceURI(exportVo.S3URI)
		if exportVo.S3RoleArn != "" {
			details[auditlog.KeyRoleArn] = exportVo.S3RoleArn
		}
	case constant.ExportTargetTypeGCS:
		details[auditlog.KeyBucketUri] = utils.RedactSourceURI(exportVo.GCSURI)
	case constant.ExportTargetTypeAzureBlob:
		details[auditlog.KeyBucketUri] = utils.RedactSourceURI(exportVo.AzBlobURI)
	case constant.ExportTargetTypeOSS:
		details[auditlog.KeyBucketUri] = utils.RedactSourceURI(exportVo.OSSURI)
	}
	if exportVo.TableFilter != nil && len(exportVo.TableFilter.Patterns) > 0 {
		details[auditlog.KeyTableFilter] = strings.Join(exportVo.TableFilter.Patterns, ",")
	}
	if exportVo.SQL != "" {
		details[auditlog.KeyTableFilter] = exportVo.SQL
	}
	return details
}

func exportDisplayName(exportVo *vo.Export) string {
	if exportVo == nil {
		return ""
	}
	return exportVo.DisplayName
}
