package main

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

func TestDrainingKeepsLivenessAndRejectsNewWork(t *testing.T) {
	a := NewApp()
	a.ready.Store(false)
	for path, want := range map[string]int{"/ready": 503, "/work": 503, "/live": 200} {
		rr := httptest.NewRecorder()
		a.ServeHTTP(rr, httptest.NewRequest("GET", path, nil))
		if rr.Code != want {
			t.Fatal(path, rr.Code)
		}
	}
}
func TestShutdownDeadlineDoesNotKillActiveHandler(t *testing.T) {
	r, err := Start()
	if err != nil {
		t.Fatal(err)
	}
	defer r.Server.Close()
	defer r.App.Release()
	c := &http.Client{Timeout: 2 * time.Second}
	defer c.CloseIdleConnections()
	clientDone := make(chan struct{})
	go func() { _, _ = Get(c, r.URL+"/work"); close(clientDone) }()
	<-r.App.started
	ctx, cancel := context.WithCancel(context.Background())
	cancel()
	if err = r.Server.Shutdown(ctx); !errors.Is(err, context.Canceled) {
		t.Fatal(err)
	}
	select {
	case <-r.App.exited:
		t.Fatal("Shutdown killed handler")
	default:
	}
	if err = r.Server.Close(); err != nil {
		t.Fatal(err)
	}
	select {
	case <-r.App.exited:
	case <-time.After(time.Second):
		t.Fatal("handler ignored Close cancellation")
	}
	<-clientDone
	if err = <-r.Stopped; !errors.Is(err, http.ErrServerClosed) {
		t.Fatal(err)
	}
}
