// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
// SPDX-License-Identifier: MIT

package recordlayer

import (
	

	
	
)

// Header implements a TLS RecordLayer header.
type Header struct {
	ContentType    protocol.ContentType
	ContentLen     uint16
	Version        protocol.Version
	Epoch          uint16
	SequenceNumber uint64 // uint48 in spec

	// Optional Fields
	ConnectionID []byte
}

// RecordLayer enums.
const (
	// FixedHeaderSize is the size of a DTLS record header when connection IDs
	// are not in use.
	FixedHeaderSize   = 13
	MaxSequenceNumber = 0x0000FFFFFFFFFFFF
)

// Marshal encodes a TLS RecordLayer Header to binary.
func ( *Header) () ([]byte, error) {
	if .SequenceNumber > MaxSequenceNumber {
		return nil, errSequenceNumberOverflow
	}

	 := FixedHeaderSize + len(.ConnectionID)

	 := make([]byte, )
	[0] = byte(.ContentType)
	[1] = .Version.Major
	[2] = .Version.Minor
	binary.BigEndian.PutUint16([3:], .Epoch)
	util.PutBigEndianUint48([5:], .SequenceNumber)
	copy([11:11+len(.ConnectionID)], .ConnectionID)
	binary.BigEndian.PutUint16([-2:], .ContentLen)

	return , nil
}

// Unmarshal populates a TLS RecordLayer Header from binary.
func ( *Header) ( []byte) error {
	if len() < FixedHeaderSize {
		return errBufferTooSmall
	}
	.ContentType = protocol.ContentType([0])
	if .ContentType == protocol.ContentTypeConnectionID {
		// If a CID was expected the ConnectionID should have been initialized.
		if len() < FixedHeaderSize+len(.ConnectionID) {
			return errBufferTooSmall
		}
		.ConnectionID = [11 : 11+len(.ConnectionID)]
	}

	.Version.Major = [1]
	.Version.Minor = [2]
	.Epoch = binary.BigEndian.Uint16([3:])

	// SequenceNumber is stored as uint48, make into uint64
	 := make([]byte, 8)
	copy([2:], [5:11])
	.SequenceNumber = binary.BigEndian.Uint64()

	if !.Version.Equal(protocol.Version1_0) && !.Version.Equal(protocol.Version1_2) {
		return errUnsupportedProtocolVersion
	}

	return nil
}

// Size returns the total size of the header.
func ( *Header) () int {
	return FixedHeaderSize + len(.ConnectionID)
}