package qlog

import (
	
	
)

// Frame represents an HTTP/3 frame.
type Frame struct {
	Frame any
}

func ( Frame) ( *jsontext.Encoder) error {
	switch frame := .Frame.(type) {
	case DataFrame:
		return .encode()
	case HeadersFrame:
		return .encode()
	case GoAwayFrame:
		return .encode()
	case SettingsFrame:
		return .encode()
	case PushPromiseFrame:
		return .encode()
	case CancelPushFrame:
		return .encode()
	case MaxPushIDFrame:
		return .encode()
	case ReservedFrame:
		return .encode()
	case UnknownFrame:
		return .encode()
	}
	// This shouldn't happen if the code is correctly logging frames.
	// Write a null token to produce valid JSON.
	return .WriteToken(jsontext.Null)
}

// A DataFrame is a DATA frame
type DataFrame struct{}

func ( *DataFrame) ( *jsontext.Encoder) error {
	 := encoderHelper{enc: }
	.WriteToken(jsontext.BeginObject)
	.WriteToken(jsontext.String("frame_type"))
	.WriteToken(jsontext.String("data"))
	.WriteToken(jsontext.EndObject)
	return .err
}

type HeaderField struct {
	Name  string
	Value string
}

// A HeadersFrame is a HEADERS frame
type HeadersFrame struct {
	HeaderFields []HeaderField
}

func ( *HeadersFrame) ( *jsontext.Encoder) error {
	 := encoderHelper{enc: }
	.WriteToken(jsontext.BeginObject)
	.WriteToken(jsontext.String("frame_type"))
	.WriteToken(jsontext.String("headers"))
	if len(.HeaderFields) > 0 {
		.WriteToken(jsontext.String("header_fields"))
		.WriteToken(jsontext.BeginArray)
		for ,  := range .HeaderFields {
			.WriteToken(jsontext.BeginObject)
			.WriteToken(jsontext.String("name"))
			.WriteToken(jsontext.String(.Name))
			.WriteToken(jsontext.String("value"))
			.WriteToken(jsontext.String(.Value))
			.WriteToken(jsontext.EndObject)
		}
		.WriteToken(jsontext.EndArray)
	}
	.WriteToken(jsontext.EndObject)
	return .err
}

// A GoAwayFrame is a GOAWAY frame
type GoAwayFrame struct {
	StreamID quic.StreamID
}

func ( *GoAwayFrame) ( *jsontext.Encoder) error {
	 := encoderHelper{enc: }
	.WriteToken(jsontext.BeginObject)
	.WriteToken(jsontext.String("frame_type"))
	.WriteToken(jsontext.String("goaway"))
	.WriteToken(jsontext.String("id"))
	.WriteToken(jsontext.Uint(uint64(.StreamID)))
	.WriteToken(jsontext.EndObject)
	return .err
}

type SettingsFrame struct {
	MaxFieldSectionSize int64
	Datagram            *bool
	ExtendedConnect     *bool
	Other               map[uint64]uint64
}

func ( *SettingsFrame) ( *jsontext.Encoder) error {
	 := encoderHelper{enc: }
	.WriteToken(jsontext.BeginObject)
	.WriteToken(jsontext.String("frame_type"))
	.WriteToken(jsontext.String("settings"))
	.WriteToken(jsontext.String("settings"))
	.WriteToken(jsontext.BeginArray)
	if .MaxFieldSectionSize >= 0 {
		.WriteToken(jsontext.BeginObject)
		.WriteToken(jsontext.String("name"))
		.WriteToken(jsontext.String("settings_max_field_section_size"))
		.WriteToken(jsontext.String("value"))
		.WriteToken(jsontext.Uint(uint64(.MaxFieldSectionSize)))
		.WriteToken(jsontext.EndObject)
	}
	if .Datagram != nil {
		.WriteToken(jsontext.BeginObject)
		.WriteToken(jsontext.String("name"))
		.WriteToken(jsontext.String("settings_h3_datagram"))
		.WriteToken(jsontext.String("value"))
		.WriteToken(jsontext.Bool(*.Datagram))
		.WriteToken(jsontext.EndObject)
	}
	if .ExtendedConnect != nil {
		.WriteToken(jsontext.BeginObject)
		.WriteToken(jsontext.String("name"))
		.WriteToken(jsontext.String("settings_enable_connect_protocol"))
		.WriteToken(jsontext.String("value"))
		.WriteToken(jsontext.Bool(*.ExtendedConnect))
		.WriteToken(jsontext.EndObject)
	}
	if len(.Other) > 0 {
		for ,  := range .Other {
			.WriteToken(jsontext.BeginObject)
			.WriteToken(jsontext.String("name"))
			.WriteToken(jsontext.String("unknown"))
			.WriteToken(jsontext.String("name_bytes"))
			.WriteToken(jsontext.Uint())
			.WriteToken(jsontext.String("value"))
			.WriteToken(jsontext.Uint())
			.WriteToken(jsontext.EndObject)
		}
	}
	.WriteToken(jsontext.EndArray)
	.WriteToken(jsontext.EndObject)
	return .err
}

// A PushPromiseFrame is a PUSH_PROMISE frame
type PushPromiseFrame struct{}

func ( *PushPromiseFrame) ( *jsontext.Encoder) error {
	 := encoderHelper{enc: }
	.WriteToken(jsontext.BeginObject)
	.WriteToken(jsontext.String("frame_type"))
	.WriteToken(jsontext.String("push_promise"))
	.WriteToken(jsontext.EndObject)
	return .err
}

// A CancelPushFrame is a CANCEL_PUSH frame
type CancelPushFrame struct{}

func ( *CancelPushFrame) ( *jsontext.Encoder) error {
	 := encoderHelper{enc: }
	.WriteToken(jsontext.BeginObject)
	.WriteToken(jsontext.String("frame_type"))
	.WriteToken(jsontext.String("cancel_push"))
	.WriteToken(jsontext.EndObject)
	return .err
}

// A MaxPushIDFrame is a MAX_PUSH_ID frame
type MaxPushIDFrame struct{}

func ( *MaxPushIDFrame) ( *jsontext.Encoder) error {
	 := encoderHelper{enc: }
	.WriteToken(jsontext.BeginObject)
	.WriteToken(jsontext.String("frame_type"))
	.WriteToken(jsontext.String("max_push_id"))
	.WriteToken(jsontext.EndObject)
	return .err
}

// A ReservedFrame is one of the reserved frame types
type ReservedFrame struct {
	Type uint64
}

func ( *ReservedFrame) ( *jsontext.Encoder) error {
	 := encoderHelper{enc: }
	.WriteToken(jsontext.BeginObject)
	.WriteToken(jsontext.String("frame_type"))
	.WriteToken(jsontext.String("reserved"))
	.WriteToken(jsontext.String("frame_type_bytes"))
	.WriteToken(jsontext.Uint(.Type))
	.WriteToken(jsontext.EndObject)
	return .err
}

// An UnknownFrame is an unknown frame type
type UnknownFrame struct {
	Type uint64
}

func ( *UnknownFrame) ( *jsontext.Encoder) error {
	 := encoderHelper{enc: }
	.WriteToken(jsontext.BeginObject)
	.WriteToken(jsontext.String("frame_type"))
	.WriteToken(jsontext.String("unknown"))
	.WriteToken(jsontext.String("frame_type_bytes"))
	.WriteToken(jsontext.Uint(.Type))
	.WriteToken(jsontext.EndObject)
	return .err
}