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

package proto

import (
	
	
	

	
)

// ChannelNumber represents CHANNEL-NUMBER attribute.
//
// The CHANNEL-NUMBER attribute contains the number of the channel.
//
// RFC 5766 Section 14.1.
type ChannelNumber uint16 // Encoded as uint16

func ( ChannelNumber) () string { return strconv.Itoa(int()) }

// 16 bits of uint + 16 bits of RFFU = 0.
const channelNumberSize = 4

// AddTo adds CHANNEL-NUMBER to message.
func ( ChannelNumber) ( *stun.Message) error {
	 := make([]byte, channelNumberSize)
	binary.BigEndian.PutUint16([:2], uint16())
	// v[2:4] are zeroes (RFFU = 0)
	.Add(stun.AttrChannelNumber, )

	return nil
}

// GetFrom decodes CHANNEL-NUMBER from message.
func ( *ChannelNumber) ( *stun.Message) error {
	,  := .Get(stun.AttrChannelNumber)
	if  != nil {
		return 
	}
	if  = stun.CheckSize(stun.AttrChannelNumber, len(), channelNumberSize);  != nil {
		return 
	}
	_ = [channelNumberSize-1] // Asserting length
	* = ChannelNumber(binary.BigEndian.Uint16([:2]))
	// v[2:4] is RFFU and equals to 0.
	return nil
}

// See https://tools.ietf.org/html/rfc5766#section-11:
//
// 0x4000 through 0x7FFF: These values are the allowed channel
// numbers (16,383 possible values).
const (
	MinChannelNumber = 0x4000
	MaxChannelNumber = 0x7FFF
)

// ErrInvalidChannelNumber means that channel number is not valid as by RFC 5766 Section 11.
var ErrInvalidChannelNumber = errors.New("channel number not in [0x4000, 0x7FFF]")

// isChannelNumberValid returns true if c in [0x4000, 0x7FFF].
func isChannelNumberValid( uint16) bool {
	return  >= MinChannelNumber &&  <= MaxChannelNumber
}

// Valid returns true if channel number has correct value that complies RFC 5766 Section 11 range.
func ( ChannelNumber) () bool {
	return isChannelNumberValid(uint16())
}