// Copyright 2024 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 (
	"math"
	"time"
)

// Config must be kept in sync with net/http.HTTP2Config.
type Config struct {
	MaxConcurrentStreams          int
	StrictMaxConcurrentRequests   bool
	MaxDecoderHeaderTableSize     int
	MaxEncoderHeaderTableSize     int
	MaxReadFrameSize              int
	MaxReceiveBufferPerConnection int
	MaxReceiveBufferPerStream     int
	SendPingTimeout               time.Duration
	PingTimeout                   time.Duration
	WriteByteTimeout              time.Duration
	PermitProhibitedCipherSuites  bool
	CountError                    func(errType string)
}

func configFromServer(h1 ServerConfig) Config {
	conf := Config{}
	fillNetHTTPConfig(&conf, h1.HTTP2Config())
	setConfigDefaults(&conf, true)
	return conf
}

func configFromTransport(h2 *Transport) Config {
	conf := Config{}
	if h2.t1 != nil {
		fillNetHTTPConfig(&conf, h2.t1.HTTP2Config())
	}
	setConfigDefaults(&conf, false)
	return conf
}

func setDefault[T ~int | ~int32 | ~uint32 | ~int64](v *T, minval, maxval, defval T) {
	if *v < minval || *v > maxval {
		*v = defval
	}
}

func setConfigDefaults(conf *Config, server bool) {
	setDefault(&conf.MaxConcurrentStreams, 1, math.MaxInt32, defaultMaxStreams)
	setDefault(&conf.MaxEncoderHeaderTableSize, 1, math.MaxInt32, initialHeaderTableSize)
	setDefault(&conf.MaxDecoderHeaderTableSize, 1, math.MaxInt32, initialHeaderTableSize)
	if server {
		setDefault(&conf.MaxReceiveBufferPerConnection, initialWindowSize, math.MaxInt32, 1<<20)
	} else {
		setDefault(&conf.MaxReceiveBufferPerConnection, initialWindowSize, math.MaxInt32, transportDefaultConnFlow)
	}
	if server {
		setDefault(&conf.MaxReceiveBufferPerStream, 1, math.MaxInt32, 1<<20)
	} else {
		setDefault(&conf.MaxReceiveBufferPerStream, 1, math.MaxInt32, transportDefaultStreamFlow)
	}
	setDefault(&conf.MaxReadFrameSize, minMaxFrameSize, maxFrameSize, defaultMaxReadFrameSize)
	setDefault(&conf.PingTimeout, 1, math.MaxInt64, 15*time.Second)
}

// adjustHTTP1MaxHeaderSize converts a limit in bytes on the size of an HTTP/1 header
// to an HTTP/2 MAX_HEADER_LIST_SIZE value.
func adjustHTTP1MaxHeaderSize(n int64) int64 {
	// http2's count is in a slightly different unit and includes 32 bytes per pair.
	// So, take the net/http.Server value and pad it up a bit, assuming 10 headers.
	const perFieldOverhead = 32 // per http2 spec
	const typicalHeaders = 10   // conservative
	return n + typicalHeaders*perFieldOverhead
}

func fillNetHTTPConfig(conf *Config, h2 Config) {
	if h2.MaxConcurrentStreams != 0 {
		conf.MaxConcurrentStreams = h2.MaxConcurrentStreams
	}
	if h2.StrictMaxConcurrentRequests {
		conf.StrictMaxConcurrentRequests = true
	}
	if h2.MaxEncoderHeaderTableSize != 0 {
		conf.MaxEncoderHeaderTableSize = h2.MaxEncoderHeaderTableSize
	}
	if h2.MaxDecoderHeaderTableSize != 0 {
		conf.MaxDecoderHeaderTableSize = h2.MaxDecoderHeaderTableSize
	}
	if h2.MaxConcurrentStreams != 0 {
		conf.MaxConcurrentStreams = h2.MaxConcurrentStreams
	}
	if h2.MaxReadFrameSize != 0 {
		conf.MaxReadFrameSize = h2.MaxReadFrameSize
	}
	if h2.MaxReceiveBufferPerConnection != 0 {
		conf.MaxReceiveBufferPerConnection = h2.MaxReceiveBufferPerConnection
	}
	if h2.MaxReceiveBufferPerStream != 0 {
		conf.MaxReceiveBufferPerStream = h2.MaxReceiveBufferPerStream
	}
	if h2.SendPingTimeout != 0 {
		conf.SendPingTimeout = h2.SendPingTimeout
	}
	if h2.PingTimeout != 0 {
		conf.PingTimeout = h2.PingTimeout
	}
	if h2.WriteByteTimeout != 0 {
		conf.WriteByteTimeout = h2.WriteByteTimeout
	}
	if h2.PermitProhibitedCipherSuites {
		conf.PermitProhibitedCipherSuites = true
	}
	if h2.CountError != nil {
		conf.CountError = h2.CountError
	}
}
