package securityevents

import (
	"context"
	"encoding/base64"
	"encoding/json"
	"net/http"
	"net/http/httptest"
	"os"
	"path/filepath"
	"sync"
	"testing"
)

func TestKubernetesSecretStoreUsesOnePreprovisionedSecret(t *testing.T) {
	var mutex sync.Mutex
	data := map[string]string{}
	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.URL.Path != "/api/v1/namespaces/easyai/secrets/easyai-gateway-security-events" || r.Header.Get("Authorization") != "Bearer service-account-token" {
			t.Fatalf("unexpected Kubernetes request: %s authorization=%t", r.URL.Path, r.Header.Get("Authorization") != "")
		}
		mutex.Lock()
		defer mutex.Unlock()
		switch r.Method {
		case http.MethodGet:
			_ = json.NewEncoder(w).Encode(map[string]any{"data": data})
		case http.MethodPatch:
			var patch struct {
				Data map[string]*string `json:"data"`
			}
			if err := json.NewDecoder(r.Body).Decode(&patch); err != nil {
				t.Fatal(err)
			}
			for key, value := range patch.Data {
				if value == nil {
					delete(data, key)
				} else {
					data[key] = *value
				}
			}
			_ = json.NewEncoder(w).Encode(map[string]any{"data": data})
		default:
			http.Error(w, "unsupported", http.StatusMethodNotAllowed)
		}
	}))
	defer server.Close()
	tokenFile := filepath.Join(t.TempDir(), "token")
	if err := os.WriteFile(tokenFile, []byte("service-account-token\n"), 0o600); err != nil {
		t.Fatal(err)
	}
	secrets, err := NewKubernetesSecretStore(KubernetesSecretStoreConfig{
		Namespace: "easyai", SecretName: "easyai-gateway-security-events", APIServer: server.URL,
		TokenFile: tokenFile, HTTPClient: server.Client(),
	})
	if err != nil {
		t.Fatal(err)
	}
	value := []byte("0123456789abcdef0123456789abcdef")
	if err := secrets.Put(context.Background(), "ssf-push-connection", value); err != nil {
		t.Fatal(err)
	}
	if data["ssf-push-connection"] != base64.StdEncoding.EncodeToString(value) {
		t.Fatal("Push Bearer was not stored in Kubernetes Secret data")
	}
	loaded, err := secrets.Get(context.Background(), "ssf-push-connection")
	if err != nil || string(loaded) != string(value) {
		t.Fatalf("loaded secret mismatch: err=%v", err)
	}
	clear(loaded)
	if err := secrets.Delete(context.Background(), "ssf-push-connection"); err != nil {
		t.Fatal(err)
	}
	if _, ok := data["ssf-push-connection"]; ok {
		t.Fatal("Push Bearer key was not removed")
	}
}

func TestKubernetesSecretStoreRejectsUnprovisionedSecret(t *testing.T) {
	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { http.NotFound(w, nil) }))
	defer server.Close()
	tokenFile := filepath.Join(t.TempDir(), "token")
	if err := os.WriteFile(tokenFile, []byte("token"), 0o600); err != nil {
		t.Fatal(err)
	}
	secrets, err := NewKubernetesSecretStore(KubernetesSecretStoreConfig{
		Namespace: "easyai", SecretName: "easyai-gateway-security-events", APIServer: server.URL,
		TokenFile: tokenFile, HTTPClient: server.Client(),
	})
	if err != nil {
		t.Fatal(err)
	}
	if err := secrets.Put(context.Background(), "ssf-push-connection", []byte("0123456789abcdef0123456789abcdef")); err == nil {
		t.Fatal("missing pre-provisioned Kubernetes Secret was accepted")
	}
}
