package authentik

import (
	"context"
	"testing"
	"time"
)

func TestFlowExecutorGetChallenge(t *testing.T) {
	t.Parallel()
	fe, err := NewFlowExecutor("http://localhost:9000", "test-flow")
	if err != nil {
		t.Fatal(err)
	}
	if fe.slug != "test-flow" {
		t.Fatalf("slug = %q", fe.slug)
	}
}

func TestFlowDone(t *testing.T) {
	t.Parallel()
	done, denied := FlowDone(FlowChallenge{"component": "xak-flow-redirect"})
	if !done || denied {
		t.Fatalf("redirect: done=%v denied=%v", done, denied)
	}
	done, denied = FlowDone(FlowChallenge{"component": "ak-stage-access-denied"})
	if !done || !denied {
		t.Fatalf("denied: done=%v denied=%v", done, denied)
	}
	done, denied = FlowDone(FlowChallenge{"component": "ak-stage-prompt"})
	if done || denied {
		t.Fatalf("prompt: done=%v denied=%v", done, denied)
	}
}

func TestFlowSessionStoreLifecycle(t *testing.T) {
	t.Parallel()
	store := NewFlowSessionStore("http://127.0.0.1:1", nil)
	_, err := store.Respond(context.Background(), "missing", "ulti-enrollment", "", map[string]any{"component": "x"})
	if err != ErrFlowSessionNotFound {
		t.Fatalf("expected ErrFlowSessionNotFound, got %v", err)
	}
}

func TestCookieRoundTrip(t *testing.T) {
	t.Parallel()
	fe, err := NewFlowExecutor("http://localhost/auth", "test-flow")
	if err != nil {
		t.Fatal(err)
	}
	fe.ImportCookies([]SerializedCookie{
		{Name: "authentik_csrf", Value: "abc123", Path: "/auth/", SameSiteName: "Lax", HTTPOnly: true},
		{Name: "authentik_session", Value: "sess", Path: "/auth/", SameSiteName: "Lax", HTTPOnly: true},
	})
	exported := fe.ExportCookies()
	if len(exported) != 2 {
		t.Fatalf("exported %d cookies", len(exported))
	}
	fe2, err := RestoreFlowExecutor("http://localhost/auth", "test-flow", exported)
	if err != nil {
		t.Fatal(err)
	}
	if fe2.csrfToken() != "abc123" {
		t.Fatalf("csrf = %q", fe2.csrfToken())
	}
	browser := BrowserAuthentikCookies(exported)
	if len(browser) != 2 || browser[0].Path != "/auth/" {
		t.Fatalf("browser cookies: %+v", browser)
	}
}

func TestFlowSessionCompleteRequiresDone(t *testing.T) {
	t.Parallel()
	store := NewFlowSessionStore("http://127.0.0.1:1", nil)
	store.mu.Lock()
	store.items["sess1"] = &flowSessionEntry{
		slug:      "default-authentication-flow",
		createdAt: time.Now(),
		completed: false,
	}
	store.mu.Unlock()
	_, err := store.CompleteSession(context.Background(), "sess1", "default-authentication-flow")
	if err != ErrFlowSessionNotCompleted {
		t.Fatalf("expected ErrFlowSessionNotCompleted, got %v", err)
	}
}