package main

import (
	"bytes"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"time"
)

func main() {
	baseURL := "http://localhost:8080"
	username := "admin"
	password := "admin"

	// Erstelle Basic Auth Header
	auth := base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", username, password)))

	// Verschiedene Aktionen und Ressourcen für realistische Testdaten
	actions := []string{"CREATE", "UPDATE", "DELETE", "UPLOAD", "SIGN", "ENABLE", "DISABLE"}
	resourceTypes := []string{"user", "space", "fqdn", "csr", "provider", "certificate"}
	usernames := []string{"admin", "user1", "user2", "operator", "manager"}

	fmt.Printf("Generiere 3000 Test-Audit-Logs...\n")

	client := &http.Client{
		Timeout: 30 * time.Second,
	}

	successCount := 0
	errorCount := 0

	for i := 0; i < 3000; i++ {
		// Wähle zufällige Werte für realistische Testdaten
		action := actions[i%len(actions)]
		resourceType := resourceTypes[i%len(resourceTypes)]
		username := usernames[i%len(usernames)]

		// Erstelle Details mit verschiedenen Informationen
		details := map[string]interface{}{
			"message":     fmt.Sprintf("Test-Log Eintrag #%d", i+1),
			"iteration":   i + 1,
			"timestamp":   time.Now().Format(time.RFC3339),
			"testData":    true,
			"resourceId":  fmt.Sprintf("test-resource-%d", i+1),
			"description": fmt.Sprintf("Dies ist ein Test-Log-Eintrag für %s %s", action, resourceType),
		}

		// Füge spezifische Details basierend auf Resource-Type hinzu
		switch resourceType {
		case "user":
			details["username"] = fmt.Sprintf("testuser%d", i+1)
			details["email"] = fmt.Sprintf("test%d@example.com", i+1)
		case "space":
			details["name"] = fmt.Sprintf("Test Space %d", i+1)
			details["description"] = "Test Space Description"
		case "fqdn":
			details["fqdn"] = fmt.Sprintf("test%d.example.com", i+1)
			details["spaceId"] = fmt.Sprintf("space-%d", i%100)
		case "csr":
			details["fqdnId"] = fmt.Sprintf("fqdn-%d", i%200)
			details["keySize"] = 2048
		case "provider":
			details["providerId"] = fmt.Sprintf("provider-%d", i%10)
			details["enabled"] = i%2 == 0
		case "certificate":
			details["certificateId"] = fmt.Sprintf("cert-%d", i+1)
			details["status"] = "issued"
		}

		// Erstelle Request Body
		requestBody := map[string]interface{}{
			"action":      action,
			"entity":      resourceType,
			"entityID":    fmt.Sprintf("test-id-%d", i+1),
			"userID":     fmt.Sprintf("user-id-%d", i%5+1),
			"username":   username,
			"details":    details,
			"ipAddress":  fmt.Sprintf("192.168.1.%d", i%255+1),
			"userAgent":  "Test-Script/1.0",
		}

		jsonData, err := json.Marshal(requestBody)
		if err != nil {
			log.Printf("Fehler beim Marshalling: %v", err)
			errorCount++
			continue
		}

		// Erstelle HTTP Request
		req, err := http.NewRequest("POST", fmt.Sprintf("%s/api/audit-logs/test", baseURL), bytes.NewBuffer(jsonData))
		if err != nil {
			log.Printf("Fehler beim Erstellen des Requests: %v", err)
			errorCount++
			continue
		}

		req.Header.Set("Content-Type", "application/json")
		req.Header.Set("Authorization", fmt.Sprintf("Basic %s", auth))

		// Sende Request
		resp, err := client.Do(req)
		if err != nil {
			log.Printf("Fehler beim Senden des Requests: %v", err)
			errorCount++
			continue
		}
		resp.Body.Close()

		if resp.StatusCode == http.StatusOK || resp.StatusCode == http.StatusCreated {
			successCount++
			if (i+1)%100 == 0 {
				fmt.Printf("Progress: %d/3000 Logs erstellt\n", i+1)
			}
		} else {
			errorCount++
			log.Printf("Unerwarteter Status Code: %d für Log %d", resp.StatusCode, i+1)
		}

		// Kleine Pause, um die Datenbank nicht zu überlasten
		if i%50 == 0 && i > 0 {
			time.Sleep(10 * time.Millisecond)
		}
	}

	fmt.Printf("\nFertig!\n")
	fmt.Printf("Erfolgreich: %d\n", successCount)
	fmt.Printf("Fehler: %d\n", errorCount)
}

