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

package datachannel

import (
	
)

// message is a parsed DataChannel message
type message interface {
	Marshal() ([]byte, error)
	Unmarshal([]byte) error
	String() string
}

// messageType is the first byte in a DataChannel message that specifies type
type messageType byte

// DataChannel Message Types
const (
	dataChannelAck  messageType = 0x02
	dataChannelOpen messageType = 0x03
)

func ( messageType) () string {
	switch  {
	case dataChannelAck:
		return "DataChannelAck"
	case dataChannelOpen:
		return "DataChannelOpen"
	default:
		return fmt.Sprintf("Unknown MessageType: %d", )
	}
}

// parse accepts raw input and returns a DataChannel message
func parse( []byte) (message, error) {
	if len() == 0 {
		return nil, ErrDataChannelMessageTooShort
	}

	var  message
	switch messageType([0]) {
	case dataChannelOpen:
		 = &channelOpen{}
	case dataChannelAck:
		 = &channelAck{}
	default:
		return nil, fmt.Errorf("%w %v", ErrInvalidMessageType, messageType([0]))
	}

	if  := .Unmarshal();  != nil {
		return nil, 
	}

	return , nil
}

// parseExpectDataChannelOpen parses a DataChannelOpen message
// or throws an error
func parseExpectDataChannelOpen( []byte) (*channelOpen, error) {
	if len() == 0 {
		return nil, ErrDataChannelMessageTooShort
	}

	if  := messageType([0]);  != dataChannelOpen {
		return nil, fmt.Errorf("%w expected(%s) actual(%s)", ErrUnexpectedDataChannelType, , dataChannelOpen)
	}

	 := &channelOpen{}
	if  := .Unmarshal();  != nil {
		return nil, 
	}

	return , nil
}

// TryMarshalUnmarshal attempts to marshal and unmarshal a message. Added for fuzzing.
func ( []byte) int {
	,  := parse()
	if  != nil {
		return 0
	}

	_,  = .Marshal()
	if  != nil {
		return 0
	}

	return 1
}