// 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 (
	"context"
	"errors"
	"time"
)

// connState is the state of a connection.
type connState int

const (
	// A connection is alive when it is first created.
	connStateAlive = connState(iota)

	// The connection has received a CONNECTION_CLOSE frame from the peer,
	// and has not yet sent a CONNECTION_CLOSE in response.
	//
	// We will send a CONNECTION_CLOSE, and then enter the draining state.
	connStatePeerClosed

	// The connection is in the closing state.
	//
	// We will send CONNECTION_CLOSE frames to the peer
	// (once upon entering the closing state, and possibly again in response to peer packets).
	//
	// If we receive a CONNECTION_CLOSE from the peer, we will enter the draining state.
	// Otherwise, we will eventually time out and move to the done state.
	//
	// https://www.rfc-editor.org/rfc/rfc9000#section-10.2.1
	connStateClosing

	// The connection is in the draining state.
	//
	// We will neither send packets nor process received packets.
	// When the drain timer expires, we move to the done state.
	//
	// https://www.rfc-editor.org/rfc/rfc9000#section-10.2.2
	connStateDraining

	// The connection is done, and the conn loop will exit.
	connStateDone
)

// lifetimeState tracks the state of a connection.
//
// This is fairly coupled to the rest of a Conn, but putting it in a struct of its own helps
// reason about operations that cause state transitions.
type lifetimeState struct {
	state connState

	readyc chan struct{} // closed when TLS handshake completes
	donec  chan struct{} // closed when finalErr is set

	localErr error // error sent to the peer
	finalErr error // error sent by the peer, or transport error; set before closing donec

	connCloseSentTime time.Time     // send time of last CONNECTION_CLOSE frame
	connCloseDelay    time.Duration // delay until next CONNECTION_CLOSE frame sent
	drainEndTime      time.Time     // time the connection exits the draining state
}

func (c *Conn) lifetimeInit() {
	c.lifetime.readyc = make(chan struct{})
	c.lifetime.donec = make(chan struct{})
}

var (
	errNoPeerResponse = errors.New("peer did not respond to CONNECTION_CLOSE")
	errConnClosed     = errors.New("connection closed")
)

// advance is called when time passes.
func (c *Conn) lifetimeAdvance(now time.Time) (done bool) {
	if c.lifetime.drainEndTime.IsZero() || c.lifetime.drainEndTime.After(now) {
		return false
	}
	// The connection drain period has ended, and we can shut down.
	// https://www.rfc-editor.org/rfc/rfc9000.html#section-10.2-7
	c.lifetime.drainEndTime = time.Time{}
	if c.lifetime.state != connStateDraining {
		// We were in the closing state, waiting for a CONNECTION_CLOSE from the peer.
		c.setFinalError(errNoPeerResponse)
	}
	c.setState(now, connStateDone)
	return true
}

// setState sets the conn state.
func (c *Conn) setState(now time.Time, state connState) {
	if c.lifetime.state == state {
		return
	}
	c.lifetime.state = state
	switch state {
	case connStateClosing, connStateDraining:
		if c.lifetime.drainEndTime.IsZero() {
			c.lifetime.drainEndTime = now.Add(3 * c.loss.ptoBasePeriod())
		}
	case connStateDone:
		c.setFinalError(nil)
	}
	if state != connStateAlive {
		c.streamsCleanup()
	}
}

// confirmHandshake is called when the TLS handshake completes.
func (c *Conn) handshakeDone() {
	close(c.lifetime.readyc)
}

// isDraining reports whether the conn is in the draining state.
//
// The draining state is entered once an endpoint receives a CONNECTION_CLOSE frame.
// The endpoint will no longer send any packets, but we retain knowledge of the connection
// until the end of the drain period to ensure we discard packets for the connection
// rather than treating them as starting a new connection.
//
// https://www.rfc-editor.org/rfc/rfc9000.html#section-10.2.2
func (c *Conn) isDraining() bool {
	switch c.lifetime.state {
	case connStateDraining, connStateDone:
		return true
	}
	return false
}

// isAlive reports whether the conn is handling packets.
func (c *Conn) isAlive() bool {
	return c.lifetime.state == connStateAlive
}

// sendOK reports whether the conn can send frames at this time.
func (c *Conn) sendOK(now time.Time) bool {
	switch c.lifetime.state {
	case connStateAlive:
		return true
	case connStatePeerClosed:
		if c.lifetime.localErr == nil {
			// We're waiting for the user to close the connection, providing us with
			// a final status to send to the peer.
			return false
		}
		// We should send a CONNECTION_CLOSE.
		return true
	case connStateClosing:
		if c.lifetime.connCloseSentTime.IsZero() {
			return true
		}
		maxRecvTime := c.acks[initialSpace].maxRecvTime
		if t := c.acks[handshakeSpace].maxRecvTime; t.After(maxRecvTime) {
			maxRecvTime = t
		}
		if t := c.acks[appDataSpace].maxRecvTime; t.After(maxRecvTime) {
			maxRecvTime = t
		}
		if maxRecvTime.Before(c.lifetime.connCloseSentTime.Add(c.lifetime.connCloseDelay)) {
			// After sending CONNECTION_CLOSE, ignore packets from the peer for
			// a delay. On the next packet received after the delay, send another
			// CONNECTION_CLOSE.
			return false
		}
		return true
	case connStateDraining:
		// We are in the draining state, and will send no more packets.
		return false
	case connStateDone:
		return false
	default:
		panic("BUG: unhandled connection state")
	}
}

// sendConnectionClose reports that the conn has sent a CONNECTION_CLOSE to the peer.
func (c *Conn) sentConnectionClose(now time.Time) {
	switch c.lifetime.state {
	case connStatePeerClosed:
		c.enterDraining(now)
	}
	if c.lifetime.connCloseSentTime.IsZero() {
		// Set the initial delay before we will send another CONNECTION_CLOSE.
		//
		// RFC 9000 states that we should rate limit CONNECTION_CLOSE frames,
		// but leaves the implementation of the limit up to us. Here, we start
		// with the same delay as the PTO timer (RFC 9002, Section 6.2.1),
		// not including max_ack_delay, and double it on every CONNECTION_CLOSE sent.
		c.lifetime.connCloseDelay = c.loss.rtt.smoothedRTT + max(4*c.loss.rtt.rttvar, timerGranularity)
	} else if !c.lifetime.connCloseSentTime.Equal(now) {
		// If connCloseSentTime == now, we're sending two CONNECTION_CLOSE frames
		// coalesced into the same datagram. We only want to increase the delay once.
		c.lifetime.connCloseDelay *= 2
	}
	c.lifetime.connCloseSentTime = now
}

// handlePeerConnectionClose handles a CONNECTION_CLOSE from the peer.
func (c *Conn) handlePeerConnectionClose(now time.Time, err error) {
	c.setFinalError(err)
	switch c.lifetime.state {
	case connStateAlive:
		c.setState(now, connStatePeerClosed)
	case connStatePeerClosed:
		// Duplicate CONNECTION_CLOSE, ignore.
	case connStateClosing:
		if c.lifetime.connCloseSentTime.IsZero() {
			c.setState(now, connStatePeerClosed)
		} else {
			c.setState(now, connStateDraining)
		}
	case connStateDraining:
	case connStateDone:
	}
}

// setFinalError records the final connection status we report to the user.
func (c *Conn) setFinalError(err error) {
	select {
	case <-c.lifetime.donec:
		return // already set
	default:
	}
	c.lifetime.finalErr = err
	close(c.lifetime.donec)
}

func (c *Conn) waitReady(ctx context.Context) error {
	select {
	case <-c.lifetime.readyc:
		return nil
	case <-c.lifetime.donec:
		return c.lifetime.finalErr
	default:
	}
	select {
	case <-c.lifetime.readyc:
		return nil
	case <-c.lifetime.donec:
		return c.lifetime.finalErr
	case <-ctx.Done():
		return ctx.Err()
	}
}

// Close closes the connection.
//
// Close is equivalent to:
//
//	conn.Abort(nil)
//	err := conn.Wait(context.Background())
func (c *Conn) Close() error {
	c.Abort(nil)
	<-c.lifetime.donec
	return c.lifetime.finalErr
}

// Wait waits for the peer to close the connection.
//
// If the connection is closed locally and the peer does not close its end of the connection,
// Wait will return with a non-nil error after the drain period expires.
//
// If the peer closes the connection with a NO_ERROR transport error, Wait returns nil.
// If the peer closes the connection with an application error, Wait returns an ApplicationError
// containing the peer's error code and reason.
// If the peer closes the connection with any other status, Wait returns a non-nil error.
func (c *Conn) Wait(ctx context.Context) error {
	if err := c.waitOnDone(ctx, c.lifetime.donec); err != nil {
		return err
	}
	return c.lifetime.finalErr
}

// Abort closes the connection and returns immediately.
//
// If err is nil, Abort sends a transport error of NO_ERROR to the peer.
// If err is an ApplicationError, Abort sends its error code and text.
// Otherwise, Abort sends a transport error of APPLICATION_ERROR with the error's text.
func (c *Conn) Abort(err error) {
	if err == nil {
		err = localTransportError{code: errNo}
	}
	c.sendMsg(func(now time.Time, c *Conn) {
		c.enterClosing(now, err)
	})
}

// abort terminates a connection with an error.
func (c *Conn) abort(now time.Time, err error) {
	c.setFinalError(err) // this error takes precedence over the peer's CONNECTION_CLOSE
	c.enterClosing(now, err)
}

// abortImmediately terminates a connection.
// The connection does not send a CONNECTION_CLOSE, and skips the draining period.
func (c *Conn) abortImmediately(now time.Time, err error) {
	c.setFinalError(err)
	c.setState(now, connStateDone)
}

// enterClosing starts an immediate close.
// We will send a CONNECTION_CLOSE to the peer and wait for their response.
func (c *Conn) enterClosing(now time.Time, err error) {
	switch c.lifetime.state {
	case connStateAlive:
		c.lifetime.localErr = err
		c.setState(now, connStateClosing)
	case connStatePeerClosed:
		c.lifetime.localErr = err
	}
}

// enterDraining moves directly to the draining state, without sending a CONNECTION_CLOSE.
func (c *Conn) enterDraining(now time.Time) {
	switch c.lifetime.state {
	case connStateAlive, connStatePeerClosed, connStateClosing:
		c.setState(now, connStateDraining)
	}
}

// exit fully terminates a connection immediately.
func (c *Conn) exit() {
	c.sendMsg(func(now time.Time, c *Conn) {
		c.abortImmediately(now, errors.New("connection closed"))
	})
}
