package store

import "strings"

const maskedAdminTaskValue = "***"

func MaskAdminGatewayTask(task AdminGatewayTask) AdminGatewayTask {
	task.Request = maskSensitiveObject(task.Request)
	task.Result = maskSensitiveObject(task.Result)
	task.Billings = maskSensitiveArray(task.Billings)
	task.Usage = maskSensitiveObject(task.Usage)
	task.Metrics = maskSensitiveObject(task.Metrics)
	task.BillingSummary = maskSensitiveObject(task.BillingSummary)
	task.PricingSnapshot = maskSensitiveObject(task.PricingSnapshot)
	task.CompatibilitySubmitHeaders = maskSensitiveObject(task.CompatibilitySubmitHeaders)
	task.CompatibilitySubmitBody = maskSensitiveObject(task.CompatibilitySubmitBody)
	task.Attempts = append([]TaskAttempt(nil), task.Attempts...)
	for index := range task.Attempts {
		task.Attempts[index].Usage = maskSensitiveObject(task.Attempts[index].Usage)
		task.Attempts[index].Metrics = maskSensitiveObject(task.Attempts[index].Metrics)
		task.Attempts[index].RequestSnapshot = maskSensitiveObject(task.Attempts[index].RequestSnapshot)
		task.Attempts[index].ResponseSnapshot = maskSensitiveObject(task.Attempts[index].ResponseSnapshot)
		task.Attempts[index].PricingSnapshot = maskSensitiveObject(task.Attempts[index].PricingSnapshot)
	}
	return task
}

func MaskTaskParamPreprocessingLogs(items []TaskParamPreprocessingLog) []TaskParamPreprocessingLog {
	masked := make([]TaskParamPreprocessingLog, len(items))
	for index, item := range items {
		item.ActualInput = maskSensitiveObject(item.ActualInput)
		item.ConvertedOutput = maskSensitiveObject(item.ConvertedOutput)
		item.Changes = maskSensitiveArray(item.Changes)
		item.ModelSnapshot = maskSensitiveObject(item.ModelSnapshot)
		masked[index] = item
	}
	return masked
}

func maskSensitiveObject(value map[string]any) map[string]any {
	if value == nil {
		return nil
	}
	masked, _ := maskSensitiveValue(value).(map[string]any)
	return masked
}

func maskSensitiveArray(value []any) []any {
	if value == nil {
		return nil
	}
	masked, _ := maskSensitiveValue(value).([]any)
	return masked
}

func maskSensitiveValue(value any) any {
	switch typed := value.(type) {
	case map[string]any:
		masked := make(map[string]any, len(typed))
		for key, item := range typed {
			if adminTaskSensitiveKey(key) {
				masked[key] = maskedAdminTaskValue
				continue
			}
			masked[key] = maskSensitiveValue(item)
		}
		return masked
	case []any:
		masked := make([]any, len(typed))
		for index, item := range typed {
			masked[index] = maskSensitiveValue(item)
		}
		return masked
	default:
		return value
	}
}

func adminTaskSensitiveKey(key string) bool {
	normalized := strings.NewReplacer("_", "", "-", "", ".", "", " ", "").Replace(strings.ToLower(strings.TrimSpace(key)))
	switch normalized {
	case "authorization", "proxyauthorization", "apikey", "xapikey", "accesstoken", "refreshtoken",
		"idtoken", "token", "secret", "clientsecret", "password", "passwd", "cookie", "setcookie",
		"credentials", "credential", "privatekey":
		return true
	default:
		return strings.HasSuffix(normalized, "apikey") ||
			strings.HasSuffix(normalized, "accesstoken") ||
			strings.HasSuffix(normalized, "refreshtoken") ||
			strings.HasSuffix(normalized, "clientsecret") ||
			strings.HasSuffix(normalized, "password") ||
			strings.HasSuffix(normalized, "privatekey")
	}
}
