// Copyright 2023 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.

//go:build go1.21

package quic

import (
	"crypto/tls"
	"log/slog"
	"math"
	"time"
)

// A Config structure configures a QUIC endpoint.
// A Config must not be modified after it has been passed to a QUIC function.
// A Config may be reused; the quic package will also not modify it.
type Config struct {
	// TLSConfig is the endpoint's TLS configuration.
	// It must be non-nil and include at least one certificate or else set GetCertificate.
	TLSConfig *tls.Config

	// MaxBidiRemoteStreams limits the number of simultaneous bidirectional streams
	// a peer may open.
	// If zero, the default value of 100 is used.
	// If negative, the limit is zero.
	MaxBidiRemoteStreams int64

	// MaxUniRemoteStreams limits the number of simultaneous unidirectional streams
	// a peer may open.
	// If zero, the default value of 100 is used.
	// If negative, the limit is zero.
	MaxUniRemoteStreams int64

	// MaxStreamReadBufferSize is the maximum amount of data sent by the peer that a
	// stream will buffer for reading.
	// If zero, the default value of 1MiB is used.
	// If negative, the limit is zero.
	MaxStreamReadBufferSize int64

	// MaxStreamWriteBufferSize is the maximum amount of data a stream will buffer for
	// sending to the peer.
	// If zero, the default value of 1MiB is used.
	// If negative, the limit is zero.
	MaxStreamWriteBufferSize int64

	// MaxConnReadBufferSize is the maximum amount of data sent by the peer that a
	// connection will buffer for reading, across all streams.
	// If zero, the default value of 1MiB is used.
	// If negative, the limit is zero.
	MaxConnReadBufferSize int64

	// RequireAddressValidation may be set to true to enable address validation
	// of client connections prior to starting the handshake.
	//
	// Enabling this setting reduces the amount of work packets with spoofed
	// source address information can cause a server to perform,
	// at the cost of increased handshake latency.
	RequireAddressValidation bool

	// StatelessResetKey is used to provide stateless reset of connections.
	// A restart may leave an endpoint without access to the state of
	// existing connections. Stateless reset permits an endpoint to respond
	// to a packet for a connection it does not recognize.
	//
	// This field should be filled with random bytes.
	// The contents should remain stable across restarts,
	// to permit an endpoint to send a reset for
	// connections created before a restart.
	//
	// The contents of the StatelessResetKey should not be exposed.
	// An attacker can use knowledge of this field's value to
	// reset existing connections.
	//
	// If this field is left as zero, stateless reset is disabled.
	StatelessResetKey [32]byte

	// HandshakeTimeout is the maximum time in which a connection handshake must complete.
	// If zero, the default of 10 seconds is used.
	// If negative, there is no handshake timeout.
	HandshakeTimeout time.Duration

	// MaxIdleTimeout is the maximum time after which an idle connection will be closed.
	// If zero, the default of 30 seconds is used.
	// If negative, idle connections are never closed.
	//
	// The idle timeout for a connection is the minimum of the maximum idle timeouts
	// of the endpoints.
	MaxIdleTimeout time.Duration

	// KeepAlivePeriod is the time after which a packet will be sent to keep
	// an idle connection alive.
	// If zero, keep alive packets are not sent.
	// If greater than zero, the keep alive period is the smaller of KeepAlivePeriod and
	// half the connection idle timeout.
	KeepAlivePeriod time.Duration

	// QLogLogger receives qlog events.
	//
	// Events currently correspond to the definitions in draft-ietf-qlog-quic-events-03.
	// This is not the latest version of the draft, but is the latest version supported
	// by common event log viewers as of the time this paragraph was written.
	//
	// The qlog package contains a slog.Handler which serializes qlog events
	// to a standard JSON representation.
	QLogLogger *slog.Logger
}

func configDefault[T ~int64](v, def, limit T) T {
	switch {
	case v == 0:
		return def
	case v < 0:
		return 0
	default:
		return min(v, limit)
	}
}

func (c *Config) maxBidiRemoteStreams() int64 {
	return configDefault(c.MaxBidiRemoteStreams, 100, maxStreamsLimit)
}

func (c *Config) maxUniRemoteStreams() int64 {
	return configDefault(c.MaxUniRemoteStreams, 100, maxStreamsLimit)
}

func (c *Config) maxStreamReadBufferSize() int64 {
	return configDefault(c.MaxStreamReadBufferSize, 1<<20, maxVarint)
}

func (c *Config) maxStreamWriteBufferSize() int64 {
	return configDefault(c.MaxStreamWriteBufferSize, 1<<20, maxVarint)
}

func (c *Config) maxConnReadBufferSize() int64 {
	return configDefault(c.MaxConnReadBufferSize, 1<<20, maxVarint)
}

func (c *Config) handshakeTimeout() time.Duration {
	return configDefault(c.HandshakeTimeout, defaultHandshakeTimeout, math.MaxInt64)
}

func (c *Config) maxIdleTimeout() time.Duration {
	return configDefault(c.MaxIdleTimeout, defaultMaxIdleTimeout, math.MaxInt64)
}

func (c *Config) keepAlivePeriod() time.Duration {
	return configDefault(c.KeepAlivePeriod, defaultKeepAlivePeriod, math.MaxInt64)
}
