// Copyright 2025 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.24

package http3

import "fmt"

// http3Error is an HTTP/3 error code.
type http3Error int

const (
	// https://www.rfc-editor.org/rfc/rfc9114.html#section-8.1
	errH3NoError              = http3Error(0x0100)
	errH3GeneralProtocolError = http3Error(0x0101)
	errH3InternalError        = http3Error(0x0102)
	errH3StreamCreationError  = http3Error(0x0103)
	errH3ClosedCriticalStream = http3Error(0x0104)
	errH3FrameUnexpected      = http3Error(0x0105)
	errH3FrameError           = http3Error(0x0106)
	errH3ExcessiveLoad        = http3Error(0x0107)
	errH3IDError              = http3Error(0x0108)
	errH3SettingsError        = http3Error(0x0109)
	errH3MissingSettings      = http3Error(0x010a)
	errH3RequestRejected      = http3Error(0x010b)
	errH3RequestCancelled     = http3Error(0x010c)
	errH3RequestIncomplete    = http3Error(0x010d)
	errH3MessageError         = http3Error(0x010e)
	errH3ConnectError         = http3Error(0x010f)
	errH3VersionFallback      = http3Error(0x0110)

	// https://www.rfc-editor.org/rfc/rfc9204.html#section-8.3
	errQPACKDecompressionFailed = http3Error(0x0200)
	errQPACKEncoderStreamError  = http3Error(0x0201)
	errQPACKDecoderStreamError  = http3Error(0x0202)
)

func (e http3Error) Error() string {
	switch e {
	case errH3NoError:
		return "H3_NO_ERROR"
	case errH3GeneralProtocolError:
		return "H3_GENERAL_PROTOCOL_ERROR"
	case errH3InternalError:
		return "H3_INTERNAL_ERROR"
	case errH3StreamCreationError:
		return "H3_STREAM_CREATION_ERROR"
	case errH3ClosedCriticalStream:
		return "H3_CLOSED_CRITICAL_STREAM"
	case errH3FrameUnexpected:
		return "H3_FRAME_UNEXPECTED"
	case errH3FrameError:
		return "H3_FRAME_ERROR"
	case errH3ExcessiveLoad:
		return "H3_EXCESSIVE_LOAD"
	case errH3IDError:
		return "H3_ID_ERROR"
	case errH3SettingsError:
		return "H3_SETTINGS_ERROR"
	case errH3MissingSettings:
		return "H3_MISSING_SETTINGS"
	case errH3RequestRejected:
		return "H3_REQUEST_REJECTED"
	case errH3RequestCancelled:
		return "H3_REQUEST_CANCELLED"
	case errH3RequestIncomplete:
		return "H3_REQUEST_INCOMPLETE"
	case errH3MessageError:
		return "H3_MESSAGE_ERROR"
	case errH3ConnectError:
		return "H3_CONNECT_ERROR"
	case errH3VersionFallback:
		return "H3_VERSION_FALLBACK"
	case errQPACKDecompressionFailed:
		return "QPACK_DECOMPRESSION_FAILED"
	case errQPACKEncoderStreamError:
		return "QPACK_ENCODER_STREAM_ERROR"
	case errQPACKDecoderStreamError:
		return "QPACK_DECODER_STREAM_ERROR"
	}
	return fmt.Sprintf("H3_ERROR_%v", int(e))
}

// A streamError is an error which terminates a stream, but not the connection.
// https://www.rfc-editor.org/rfc/rfc9114.html#section-8-1
type streamError struct {
	code    http3Error
	message string
}

func (e *streamError) Error() string { return e.message }
func (e *streamError) Unwrap() error { return e.code }

// A connectionError is an error which results in the entire connection closing.
// https://www.rfc-editor.org/rfc/rfc9114.html#section-8-2
type connectionError struct {
	code    http3Error
	message string
}

func (e *connectionError) Error() string { return e.message }
func (e *connectionError) Unwrap() error { return e.code }
