package forwarder

import (
	"context"
	"io"
	"net/http"
	"testing"
	"time"

	"github.com/stretchr/testify/require"
)

func TestMultipartCustomTransportStartsHeaderTimeoutAfterBodyEOF(t *testing.T) {
	const headerTimeout = 15 * time.Millisecond
	canceledBeforeBodyEOF := make(chan bool, 1)
	base := &http.Client{Transport: roundTripFunc(func(request *http.Request) (*http.Response, error) {
		_, err := io.Copy(io.Discard, request.Body)
		if err != nil {
			return nil, err
		}
		select {
		case <-request.Context().Done():
			canceledBeforeBodyEOF <- true
		default:
			canceledBeforeBodyEOF <- false
		}
		<-request.Context().Done()
		return nil, request.Context().Err()
	})}
	client := newMultipartStreamingHTTPClient(base, headerTimeout)

	reader, writer := io.Pipe()
	go func() {
		_, writeErr := writer.Write([]byte("before"))
		if writeErr == nil {
			bodyDelay := time.NewTimer(50 * time.Millisecond)
			defer bodyDelay.Stop()
			<-bodyDelay.C
			_, writeErr = writer.Write([]byte("after"))
		}
		if writeErr != nil {
			_ = writer.CloseWithError(writeErr)
		} else {
			_ = writer.Close()
		}
	}()
	request, err := http.NewRequestWithContext(
		context.Background(), http.MethodPost, "http://embedded.meshx/import", reader,
	)
	require.NoError(t, err)

	started := time.Now()
	_, err = client.Do(request)
	elapsed := time.Since(started)

	require.Error(t, err)
	require.False(t, <-canceledBeforeBodyEOF)
	require.GreaterOrEqual(t, elapsed, 50*time.Millisecond+headerTimeout)
}
