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

package quic

import (
	"context"
	"crypto/tls"
	"fmt"
	"testing"
	"time"
)

func TestHandshakeTimeoutExpiresServer(t *testing.T) {
	const timeout = 5 * time.Second
	tc := newTestConn(t, serverSide, func(c *Config) {
		c.HandshakeTimeout = timeout
	})
	tc.ignoreFrame(frameTypeAck)
	tc.ignoreFrame(frameTypeNewConnectionID)
	tc.writeFrames(packetTypeInitial,
		debugFrameCrypto{
			data: tc.cryptoDataIn[tls.QUICEncryptionLevelInitial],
		})
	// Server starts its end of the handshake.
	// Client acks these packets to avoid starting the PTO timer.
	tc.wantFrameType("server sends Initial CRYPTO flight",
		packetTypeInitial, debugFrameCrypto{})
	tc.writeAckForAll()
	tc.wantFrameType("server sends Handshake CRYPTO flight",
		packetTypeHandshake, debugFrameCrypto{})
	tc.writeAckForAll()

	if got, want := tc.timerDelay(), timeout; got != want {
		t.Errorf("connection timer = %v, want %v (handshake timeout)", got, want)
	}

	// Client sends a packet, but this does not extend the handshake timer.
	tc.advance(1 * time.Second)
	tc.writeFrames(packetTypeHandshake, debugFrameCrypto{
		data: tc.cryptoDataIn[tls.QUICEncryptionLevelHandshake][:1], // partial data
	})
	tc.wantIdle("handshake is not complete")

	tc.advance(timeout - 1*time.Second)
	tc.wantFrame("server closes connection after handshake timeout",
		packetTypeHandshake, debugFrameConnectionCloseTransport{
			code: errConnectionRefused,
		})
}

func TestHandshakeTimeoutExpiresClient(t *testing.T) {
	const timeout = 5 * time.Second
	tc := newTestConn(t, clientSide, func(c *Config) {
		c.HandshakeTimeout = timeout
	})
	tc.ignoreFrame(frameTypeAck)
	tc.ignoreFrame(frameTypeNewConnectionID)
	// Start the handshake.
	// The client always sets a PTO timer until it gets an ack for a handshake packet
	// or confirms the handshake, so proceed far enough through the handshake to
	// let us not worry about PTO.
	tc.wantFrameType("client sends Initial CRYPTO flight",
		packetTypeInitial, debugFrameCrypto{})
	tc.writeAckForAll()
	tc.writeFrames(packetTypeInitial,
		debugFrameCrypto{
			data: tc.cryptoDataIn[tls.QUICEncryptionLevelInitial],
		})
	tc.writeFrames(packetTypeHandshake,
		debugFrameCrypto{
			data: tc.cryptoDataIn[tls.QUICEncryptionLevelHandshake],
		})
	tc.wantFrameType("client sends Handshake CRYPTO flight",
		packetTypeHandshake, debugFrameCrypto{})
	tc.writeAckForAll()
	tc.wantIdle("client is waiting for end of handshake")

	if got, want := tc.timerDelay(), timeout; got != want {
		t.Errorf("connection timer = %v, want %v (handshake timeout)", got, want)
	}
	tc.advance(timeout)
	tc.wantFrame("client closes connection after handshake timeout",
		packetTypeHandshake, debugFrameConnectionCloseTransport{
			code: errConnectionRefused,
		})
}

func TestIdleTimeoutExpires(t *testing.T) {
	for _, test := range []struct {
		localMaxIdleTimeout time.Duration
		peerMaxIdleTimeout  time.Duration
		wantTimeout         time.Duration
	}{{
		localMaxIdleTimeout: 10 * time.Second,
		peerMaxIdleTimeout:  20 * time.Second,
		wantTimeout:         10 * time.Second,
	}, {
		localMaxIdleTimeout: 20 * time.Second,
		peerMaxIdleTimeout:  10 * time.Second,
		wantTimeout:         10 * time.Second,
	}, {
		localMaxIdleTimeout: 0,
		peerMaxIdleTimeout:  10 * time.Second,
		wantTimeout:         10 * time.Second,
	}, {
		localMaxIdleTimeout: 10 * time.Second,
		peerMaxIdleTimeout:  0,
		wantTimeout:         10 * time.Second,
	}} {
		name := fmt.Sprintf("local=%v/peer=%v", test.localMaxIdleTimeout, test.peerMaxIdleTimeout)
		t.Run(name, func(t *testing.T) {
			tc := newTestConn(t, serverSide, func(p *transportParameters) {
				p.maxIdleTimeout = test.peerMaxIdleTimeout
			}, func(c *Config) {
				c.MaxIdleTimeout = test.localMaxIdleTimeout
			})
			tc.handshake()
			if got, want := tc.timeUntilEvent(), test.wantTimeout; got != want {
				t.Errorf("new conn timeout=%v, want %v (idle timeout)", got, want)
			}
			tc.advance(test.wantTimeout - 1)
			tc.wantIdle("connection is idle and alive prior to timeout")
			ctx := canceledContext()
			if err := tc.conn.Wait(ctx); err != context.Canceled {
				t.Fatalf("conn.Wait() = %v, want Canceled", err)
			}
			tc.advance(1)
			tc.wantIdle("connection exits after timeout")
			if err := tc.conn.Wait(ctx); err != errIdleTimeout {
				t.Fatalf("conn.Wait() = %v, want errIdleTimeout", err)
			}
		})
	}
}

func TestIdleTimeoutKeepAlive(t *testing.T) {
	for _, test := range []struct {
		idleTimeout time.Duration
		keepAlive   time.Duration
		wantTimeout time.Duration
	}{{
		idleTimeout: 30 * time.Second,
		keepAlive:   10 * time.Second,
		wantTimeout: 10 * time.Second,
	}, {
		idleTimeout: 10 * time.Second,
		keepAlive:   30 * time.Second,
		wantTimeout: 5 * time.Second,
	}, {
		idleTimeout: -1, // disabled
		keepAlive:   30 * time.Second,
		wantTimeout: 30 * time.Second,
	}} {
		name := fmt.Sprintf("idle_timeout=%v/keepalive=%v", test.idleTimeout, test.keepAlive)
		t.Run(name, func(t *testing.T) {
			tc := newTestConn(t, serverSide, func(c *Config) {
				c.MaxIdleTimeout = test.idleTimeout
				c.KeepAlivePeriod = test.keepAlive
			})
			tc.handshake()
			if got, want := tc.timeUntilEvent(), test.wantTimeout; got != want {
				t.Errorf("new conn timeout=%v, want %v (keepalive timeout)", got, want)
			}
			tc.advance(test.wantTimeout - 1)
			tc.wantIdle("connection is idle prior to timeout")
			tc.advance(1)
			tc.wantFrameType("keep-alive ping is sent", packetType1RTT,
				debugFramePing{})
		})
	}
}

func TestIdleLongTermKeepAliveSent(t *testing.T) {
	// This test examines a connection sitting idle and sending periodic keep-alive pings.
	const keepAlivePeriod = 30 * time.Second
	tc := newTestConn(t, clientSide, func(c *Config) {
		c.KeepAlivePeriod = keepAlivePeriod
		c.MaxIdleTimeout = -1
	})
	tc.handshake()
	// The handshake will have completed a little bit after the point at which the
	// keepalive timer was set. Send two PING frames to the conn, triggering an immediate ack
	// and resetting the timer.
	tc.writeFrames(packetType1RTT, debugFramePing{})
	tc.writeFrames(packetType1RTT, debugFramePing{})
	tc.wantFrameType("conn acks received pings", packetType1RTT, debugFrameAck{})
	for i := 0; i < 10; i++ {
		tc.wantIdle("conn has nothing more to send")
		if got, want := tc.timeUntilEvent(), keepAlivePeriod; got != want {
			t.Errorf("i=%v conn timeout=%v, want %v (keepalive timeout)", i, got, want)
		}
		tc.advance(keepAlivePeriod)
		tc.wantFrameType("keep-alive ping is sent", packetType1RTT,
			debugFramePing{})
		tc.writeAckForAll()
	}
}

func TestIdleLongTermKeepAliveReceived(t *testing.T) {
	// This test examines a connection sitting idle, but receiving periodic peer
	// traffic to keep the connection alive.
	const idleTimeout = 30 * time.Second
	tc := newTestConn(t, serverSide, func(c *Config) {
		c.MaxIdleTimeout = idleTimeout
	})
	tc.handshake()
	for i := 0; i < 10; i++ {
		tc.advance(idleTimeout - 1*time.Second)
		tc.writeFrames(packetType1RTT, debugFramePing{})
		if got, want := tc.timeUntilEvent(), maxAckDelay-timerGranularity; got != want {
			t.Errorf("i=%v conn timeout=%v, want %v (max_ack_delay)", i, got, want)
		}
		tc.advanceToTimer()
		tc.wantFrameType("conn acks received ping", packetType1RTT, debugFrameAck{})
	}
	// Connection is still alive.
	ctx := canceledContext()
	if err := tc.conn.Wait(ctx); err != context.Canceled {
		t.Fatalf("conn.Wait() = %v, want Canceled", err)
	}
}
