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

package sdp

import (
	
)

// MediaDescription represents a media type.
// https://tools.ietf.org/html/rfc4566#section-5.14
type MediaDescription struct {
	// m=<media> <port>/<number of ports> <proto> <fmt> ...
	// https://tools.ietf.org/html/rfc4566#section-5.14
	MediaName MediaName

	// i=<session description>
	// https://tools.ietf.org/html/rfc4566#section-5.4
	MediaTitle *Information

	// c=<nettype> <addrtype> <connection-address>
	// https://tools.ietf.org/html/rfc4566#section-5.7
	ConnectionInformation *ConnectionInformation

	// b=<bwtype>:<bandwidth>
	// https://tools.ietf.org/html/rfc4566#section-5.8
	Bandwidth []Bandwidth

	// k=<method>
	// k=<method>:<encryption key>
	// https://tools.ietf.org/html/rfc4566#section-5.12
	EncryptionKey *EncryptionKey

	// a=<attribute>
	// a=<attribute>:<value>
	// https://tools.ietf.org/html/rfc4566#section-5.13
	Attributes []Attribute
}

// Attribute returns the value of an attribute and if it exists.
func ( *MediaDescription) ( string) (string, bool) {
	for ,  := range .Attributes {
		if .Key ==  {
			return .Value, true
		}
	}

	return "", false
}

// RangedPort supports special format for the media field "m=" port value. If
// it may be necessary to specify multiple transport ports, the protocol allows
// to write it as: <port>/<number of ports> where number of ports is a an
// offsetting range.
type RangedPort struct {
	Value int
	Range *int
}

func ( *RangedPort) () string {
	 := strconv.Itoa(.Value)
	if .Range != nil {
		 += "/" + strconv.Itoa(*.Range)
	}

	return 
}

func ( RangedPort) ( []byte) []byte {
	 = strconv.AppendInt(, int64(.Value), 10)
	if .Range != nil {
		 = append(, '/')
		 = strconv.AppendInt(, int64(*.Range), 10)
	}

	return 
}

func ( RangedPort) () ( int) {
	 = lenInt(int64(.Value))
	if .Range != nil {
		 += 1 + lenInt(int64(*.Range))
	}

	return
}

// MediaName describes the "m=" field storage structure.
type MediaName struct {
	Media   string
	Port    RangedPort
	Protos  []string
	Formats []string
}

func ( MediaName) () string {
	return stringFromMarshal(.marshalInto, .marshalSize)
}

func ( MediaName) ( []byte) []byte {
	 := func( []string,  byte) {
		for ,  := range  {
			if  != 0 &&  != len() {
				 = append(, )
			}
			 = append(, ...)
		}
	}

	 = append(append(, .Media...), ' ')
	 = append(.Port.marshalInto(), ' ')
	(.Protos, '/')
	 = append(, ' ')
	(.Formats, ' ')

	return 
}

func ( MediaName) () ( int) {
	 := func( []string) {
		for ,  := range  {
			 += 1 + len()
		}
	}

	 = len(.Media)
	 += 1 + .Port.marshalSize()
	(.Protos)
	(.Formats)

	return 
}