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

package recordlayer

import (
	

	
	
	
)

// RecordLayer which handles all data transport.
// The record layer is assumed to sit directly on top of some
// reliable transport such as TCP. The record layer can carry four types of content:
//
// 1. Handshake messages—used for algorithm negotiation and key establishment.
// 2. ChangeCipherSpec messages—really part of the handshake but technically a separate kind of message.
// 3. Alert messages—used to signal that errors have occurred
// 4. Application layer data
//
// The DTLS record layer is extremely similar to that of TLS 1.1.  The
// only change is the inclusion of an explicit sequence number in the
// record.  This sequence number allows the recipient to correctly
// verify the TLS MAC.
//
// https://tools.ietf.org/html/rfc4347#section-4.1
type RecordLayer struct {
	Header  Header
	Content protocol.Content
}

// Marshal encodes the RecordLayer to binary
func ( *RecordLayer) () ([]byte, error) {
	,  := .Content.Marshal()
	if  != nil {
		return nil, 
	}

	.Header.ContentLen = uint16(len())
	.Header.ContentType = .Content.ContentType()

	,  := .Header.Marshal()
	if  != nil {
		return nil, 
	}

	return append(, ...), nil
}

// Unmarshal populates the RecordLayer from binary
func ( *RecordLayer) ( []byte) error {
	if len() < HeaderSize {
		return errBufferTooSmall
	}
	if  := .Header.Unmarshal();  != nil {
		return 
	}

	switch protocol.ContentType([0]) {
	case protocol.ContentTypeChangeCipherSpec:
		.Content = &protocol.ChangeCipherSpec{}
	case protocol.ContentTypeAlert:
		.Content = &alert.Alert{}
	case protocol.ContentTypeHandshake:
		.Content = &handshake.Handshake{}
	case protocol.ContentTypeApplicationData:
		.Content = &protocol.ApplicationData{}
	default:
		return errInvalidContentType
	}

	return .Content.Unmarshal([HeaderSize:])
}

// UnpackDatagram extracts all RecordLayer messages from a single datagram.
// Note that as with TLS, multiple handshake messages may be placed in
// the same DTLS record, provided that there is room and that they are
// part of the same flight.  Thus, there are two acceptable ways to pack
// two DTLS messages into the same datagram: in the same record or in
// separate records.
// https://tools.ietf.org/html/rfc6347#section-4.2.3
func ( []byte) ([][]byte, error) {
	 := [][]byte{}

	for  := 0; len() != ; {
		if len()- <= HeaderSize {
			return nil, ErrInvalidPacketLength
		}

		 := (HeaderSize + int(binary.BigEndian.Uint16([+11:])))
		if + > len() {
			return nil, ErrInvalidPacketLength
		}

		 = append(, [:+])
		 += 
	}

	return , nil
}