// 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"
	"crypto/tls"
	"errors"
	"fmt"
	"time"
)

// startTLS starts the TLS handshake.
func (c *Conn) startTLS(now time.Time, initialConnID []byte, params transportParameters) error {
	c.keysInitial = initialKeys(initialConnID, c.side)

	qconfig := &tls.QUICConfig{TLSConfig: c.config.TLSConfig}
	if c.side == clientSide {
		c.tls = tls.QUICClient(qconfig)
	} else {
		c.tls = tls.QUICServer(qconfig)
	}
	c.tls.SetTransportParameters(marshalTransportParameters(params))
	// TODO: We don't need or want a context for cancelation here,
	// but users can use a context to plumb values through to hooks defined
	// in the tls.Config. Pass through a context.
	if err := c.tls.Start(context.TODO()); err != nil {
		return err
	}
	return c.handleTLSEvents(now)
}

func (c *Conn) handleTLSEvents(now time.Time) error {
	for {
		e := c.tls.NextEvent()
		if c.testHooks != nil {
			c.testHooks.handleTLSEvent(e)
		}
		switch e.Kind {
		case tls.QUICNoEvent:
			return nil
		case tls.QUICSetReadSecret:
			if err := checkCipherSuite(e.Suite); err != nil {
				return err
			}
			switch e.Level {
			case tls.QUICEncryptionLevelHandshake:
				c.keysHandshake.r.init(e.Suite, e.Data)
			case tls.QUICEncryptionLevelApplication:
				c.keysAppData.r.init(e.Suite, e.Data)
			}
		case tls.QUICSetWriteSecret:
			if err := checkCipherSuite(e.Suite); err != nil {
				return err
			}
			switch e.Level {
			case tls.QUICEncryptionLevelHandshake:
				c.keysHandshake.w.init(e.Suite, e.Data)
			case tls.QUICEncryptionLevelApplication:
				c.keysAppData.w.init(e.Suite, e.Data)
			}
		case tls.QUICWriteData:
			var space numberSpace
			switch e.Level {
			case tls.QUICEncryptionLevelInitial:
				space = initialSpace
			case tls.QUICEncryptionLevelHandshake:
				space = handshakeSpace
			case tls.QUICEncryptionLevelApplication:
				space = appDataSpace
			default:
				return fmt.Errorf("quic: internal error: write handshake data at level %v", e.Level)
			}
			c.crypto[space].write(e.Data)
		case tls.QUICHandshakeDone:
			if c.side == serverSide {
				// "[...] the TLS handshake is considered confirmed
				// at the server when the handshake completes."
				// https://www.rfc-editor.org/rfc/rfc9001#section-4.1.2-1
				c.confirmHandshake(now)
			}
			c.handshakeDone()
		case tls.QUICTransportParameters:
			params, err := unmarshalTransportParams(e.Data)
			if err != nil {
				return err
			}
			if err := c.receiveTransportParameters(params); err != nil {
				return err
			}
		}
	}
}

// handleCrypto processes data received in a CRYPTO frame.
func (c *Conn) handleCrypto(now time.Time, space numberSpace, off int64, data []byte) error {
	var level tls.QUICEncryptionLevel
	switch space {
	case initialSpace:
		level = tls.QUICEncryptionLevelInitial
	case handshakeSpace:
		level = tls.QUICEncryptionLevelHandshake
	case appDataSpace:
		level = tls.QUICEncryptionLevelApplication
	default:
		return errors.New("quic: internal error: received CRYPTO frame in unexpected number space")
	}
	err := c.crypto[space].handleCrypto(off, data, func(b []byte) error {
		return c.tls.HandleData(level, b)
	})
	if err != nil {
		return err
	}
	return c.handleTLSEvents(now)
}
