package llm

import (
	"context"
	"net/http"
	"net/http/httptest"
	"testing"
	"time"
)

func TestRouter_PrimarySucceeds(t *testing.T) {
	primary := mockServer(t, "from-primary")
	defer primary.Close()
	fallback := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		t.Error("fallback must not be called when primary succeeds")
	}))
	defer fallback.Close()

	r := &Router{
		Primary:  New(primary.URL, "", "m", time.Second),
		Fallback: New(fallback.URL, "", "m", time.Second),
	}
	out, err := r.Complete(context.Background(), "sys", "user")
	if err != nil {
		t.Fatalf("Complete: %v", err)
	}
	if out != "from-primary" {
		t.Errorf("got %q, want %q", out, "from-primary")
	}
}

func TestRouter_FallsBackOnPrimaryError(t *testing.T) {
	primary := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		http.Error(w, "unavailable", http.StatusServiceUnavailable)
	}))
	defer primary.Close()
	fallback := mockServer(t, "from-fallback")
	defer fallback.Close()

	r := &Router{
		Primary:  New(primary.URL, "", "m", time.Second),
		Fallback: New(fallback.URL, "", "m", time.Second),
	}
	out, err := r.Complete(context.Background(), "sys", "user")
	if err != nil {
		t.Fatalf("Complete: %v", err)
	}
	if out != "from-fallback" {
		t.Errorf("got %q, want %q", out, "from-fallback")
	}
}

func TestRouter_BothFail(t *testing.T) {
	fail := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		http.Error(w, "err", http.StatusBadGateway)
	}))
	defer fail.Close()

	r := &Router{
		Primary:  New(fail.URL, "", "m", time.Second),
		Fallback: New(fail.URL, "", "m", time.Second),
	}
	if _, err := r.Complete(context.Background(), "sys", "user"); err == nil {
		t.Fatal("want error when both fail, got nil")
	}
}

func TestRouter_NilFallback(t *testing.T) {
	fail := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		http.Error(w, "err", http.StatusBadGateway)
	}))
	defer fail.Close()

	r := &Router{Primary: New(fail.URL, "", "m", time.Second)}
	if _, err := r.Complete(context.Background(), "sys", "user"); err == nil {
		t.Fatal("want error with nil fallback, got nil")
	}
}
