// Copyright 2026 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package http2

import (
	"context"
	"fmt"
	"net"
	"net/http"
	"net/textproto"
	"sync"
	"testing"
	"time"

	"golang.org/x/net/http2/hpack"
	"golang.org/x/net/internal/httpcommon"
)

const (
	DefaultMaxReadFrameSize     = defaultMaxReadFrameSize
	DefaultMaxStreams           = defaultMaxStreams
	InflowMinRefresh            = inflowMinRefresh
	InitialHeaderTableSize      = initialHeaderTableSize
	InitialMaxConcurrentStreams = initialMaxConcurrentStreams
	InitialWindowSize           = initialWindowSize
	MaxFrameSize                = maxFrameSize
	MaxQueuedControlFrames      = maxQueuedControlFrames
	MinMaxFrameSize             = minMaxFrameSize
)

type (
	ServerConn  = serverConn
	Stream      = stream
	StreamState = streamState

	PseudoHeaderError     = pseudoHeaderError
	HeaderFieldNameError  = headerFieldNameError
	HeaderFieldValueError = headerFieldValueError
)

const (
	StateIdle             = stateIdle
	StateOpen             = stateOpen
	StateHalfClosedLocal  = stateHalfClosedLocal
	StateHalfClosedRemote = stateHalfClosedRemote
	StateClosed           = stateClosed
)

var (
	ErrClientConnForceClosed       = errClientConnForceClosed
	ErrClientConnNotEstablished    = errClientConnNotEstablished
	ErrClientConnUnusable          = errClientConnUnusable
	ErrExtendedConnectNotSupported = errExtendedConnectNotSupported
	ErrReqBodyTooLong              = errReqBodyTooLong
	ErrRequestHeaderListSize       = errRequestHeaderListSize
	ErrResponseHeaderListSize      = errResponseHeaderListSize
)

func (s *Server) TestServeConn(c net.Conn, opts *ServeConnOpts, newf func(*serverConn)) {
	s.serveConn(c, opts, newf)
}

func (sc *serverConn) TestFlowControlConsumed() (consumed int32) {
	conf := configFromServer(sc.hs, sc.srv)
	donec := make(chan struct{})
	sc.sendServeMsg(func(sc *serverConn) {
		defer close(donec)
		initial := conf.MaxUploadBufferPerConnection
		avail := sc.inflow.avail + sc.inflow.unsent
		consumed = initial - avail
	})
	<-donec
	return consumed
}

func (sc *serverConn) TestStreamExists(id uint32) bool {
	ch := make(chan bool, 1)
	sc.serveMsgCh <- func(int) {
		ch <- (sc.streams[id] != nil)
	}
	return <-ch
}

func (sc *serverConn) TestStreamState(id uint32) streamState {
	ch := make(chan streamState, 1)
	sc.serveMsgCh <- func(int) {
		state, _ := sc.state(id)
		ch <- state
	}
	return <-ch
}

func (sc *serverConn) StartGracefulShutdown() { sc.startGracefulShutdown() }

func (sc *serverConn) TestHPACKEncoder() *hpack.Encoder {
	return sc.hpackEncoder
}

func (sc *serverConn) TestFramerMaxHeaderStringLen() int {
	return sc.framer.maxHeaderStringLen()
}

func (t *Transport) DialClientConn(ctx context.Context, addr string, singleUse bool) (*ClientConn, error) {
	return t.dialClientConn(ctx, addr, singleUse)
}

func (t *Transport) TestNewClientConn(c net.Conn, singleUse bool, internalStateHook func()) (*ClientConn, error) {
	return t.newClientConn(c, singleUse, internalStateHook)
}

func (t *Transport) TestSetNewClientConnHook(f func(*ClientConn)) {
	t.transportTestHooks = &transportTestHooks{
		newclientconn: f,
	}
}

func (t *Transport) TestTransport() *http.Transport {
	if t.t1 == nil {
		t.t1 = &http.Transport{}
	}
	return t.t1
}

func (cc *ClientConn) TestNetConn() net.Conn     { return cc.tconn }
func (cc *ClientConn) TestSetNetConn(c net.Conn) { cc.tconn = c }
func (cc *ClientConn) TestRoundTrip(req *http.Request, f func(stremaID uint32)) (*http.Response, error) {
	return cc.roundTrip(req, func(cs *clientStream) {
		f(cs.ID)
	})
}

func (cc *ClientConn) TestHPACKEncoder() *hpack.Encoder {
	return cc.henc
}

func (cc *ClientConn) TestPeerMaxHeaderTableSize() uint32 {
	cc.mu.Lock()
	defer cc.mu.Unlock()
	return cc.peerMaxHeaderTableSize
}

func (cc *ClientConn) TestInflowWindow(streamID uint32) (int32, error) {
	cc.mu.Lock()
	defer cc.mu.Unlock()
	if streamID == 0 {
		return cc.inflow.avail + cc.inflow.unsent, nil
	}
	cs := cc.streams[streamID]
	if cs == nil {
		return -1, fmt.Errorf("no stream with id %v", streamID)
	}
	return cs.inflow.avail + cs.inflow.unsent, nil
}

func (fr *Framer) TestSetDebugReadLoggerf(f func(string, ...any)) {
	fr.logReads = true
	fr.debugReadLoggerf = f
}

func (fr *Framer) TestSetDebugWriteLoggerf(f func(string, ...any)) {
	fr.logWrites = true
	fr.debugWriteLoggerf = f
}

func SummarizeFrame(f Frame) string {
	return summarizeFrame(f)
}

func SetTestHookGetServerConn(t testing.TB, f func(*serverConn)) {
	SetForTest(t, &testHookGetServerConn, f)
}

func init() {
	testHookOnPanicMu = new(sync.Mutex)
}

func SetTestHookOnPanic(t testing.TB, f func(sc *serverConn, panicVal interface{}) (rePanic bool)) {
	testHookOnPanicMu.Lock()
	defer testHookOnPanicMu.Unlock()
	old := testHookOnPanic
	testHookOnPanic = f
	t.Cleanup(func() {
		testHookOnPanicMu.Lock()
		defer testHookOnPanicMu.Unlock()
		testHookOnPanic = old
	})
}

func SetTestHookGot1xx(t testing.TB, f func(int, textproto.MIMEHeader) error) {
	SetForTest(t, &got1xxFuncForTests, f)
}

func SetDisableExtendedConnectProtocol(t testing.TB, v bool) {
	SetForTest(t, &disableExtendedConnectProtocol, v)
}

func LogFrameReads() bool  { return logFrameReads }
func LogFrameWrites() bool { return logFrameWrites }

const GoAwayTimeout = 25 * time.Millisecond

func init() {
	goAwayTimeout = GoAwayTimeout
}

func EncodeHeaderRaw(t testing.TB, headers ...string) []byte {
	return encodeHeaderRaw(t, headers...)
}

func NewPriorityWriteSchedulerRFC7540(cfg *PriorityWriteSchedulerConfig) WriteScheduler {
	return newPriorityWriteSchedulerRFC7540(cfg)
}

func NewPriorityWriteSchedulerRFC9218() WriteScheduler {
	return newPriorityWriteSchedulerRFC9218()
}

func NewRoundRobinWriteScheduler() WriteScheduler {
	return newRoundRobinWriteScheduler()
}

func DisableGoroutineTracking(t testing.TB) {
	disableDebugGoroutines.Store(true)
	t.Cleanup(func() {
		disableDebugGoroutines.Store(false)
	})
}

func InvalidHTTP1LookingFrameHeader() FrameHeader {
	return invalidHTTP1LookingFrameHeader()
}

func NewNoDialClientConnPool() ClientConnPool {
	return noDialClientConnPool{new(clientConnPool)}
}

func EncodeRequestHeaders(req *http.Request, addGzipHeader bool, peerMaxHeaderListSize uint64, headerf func(name, value string)) (httpcommon.EncodeHeadersResult, error) {
	return encodeRequestHeaders(req, addGzipHeader, peerMaxHeaderListSize, headerf)
}
