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

package sdp

import (
	
)

// Information describes the "i=" field which provides textual information
// about the session.
type Information string

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

func ( Information) ( []byte) []byte {
	return append(, ...)
}

func ( Information) () ( int) {
	return len()
}

// ConnectionInformation defines the representation for the "c=" field
// containing connection data.
type ConnectionInformation struct {
	NetworkType string
	AddressType string
	Address     *Address
}

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

func ( ConnectionInformation) ( []byte) []byte {
	 = append(append(, .NetworkType...), ' ')
	 = append(, .AddressType...)

	if .Address != nil {
		 = append(, ' ')
		 = .Address.marshalInto()
	}

	return 
}

func ( ConnectionInformation) () ( int) {
	 = len(.NetworkType)
	 += 1 + len(.AddressType)
	if .Address != nil {
		 += 1 + .Address.marshalSize()
	}

	return
}

// Address desribes a structured address token from within the "c=" field.
type Address struct {
	Address string
	TTL     *int
	Range   *int
}

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

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

	return 
}

func ( Address) () ( int) {
	 = len(.Address)
	if .TTL != nil {
		 += 1 + lenUint(uint64(*.TTL)) //nolint:gosec // G115
	}
	if .Range != nil {
		 += 1 + lenUint(uint64(*.Range)) //nolint:gosec // G115
	}

	return
}

// Bandwidth describes an optional field which denotes the proposed bandwidth
// to be used by the session or media.
type Bandwidth struct {
	Experimental bool
	Type         string
	Bandwidth    uint64
}

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

func ( Bandwidth) ( []byte) []byte {
	if .Experimental {
		 = append(, "X-"...)
	}
	 = append(append(, .Type...), ':')

	return strconv.AppendUint(, .Bandwidth, 10)
}

func ( Bandwidth) () ( int) {
	if .Experimental {
		 += 2
	}

	 += len(.Type) + 1 + lenUint(.Bandwidth)

	return
}

// EncryptionKey describes the "k=" which conveys encryption key information.
type EncryptionKey string

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

func ( EncryptionKey) ( []byte) []byte {
	return append(, ...)
}

func ( EncryptionKey) () ( int) {
	return len()
}

// Attribute describes the "a=" field which represents the primary means for
// extending SDP.
type Attribute struct {
	Key   string
	Value string
}

// NewPropertyAttribute constructs a new attribute.
func ( string) Attribute {
	return Attribute{
		Key: ,
	}
}

// NewAttribute constructs a new attribute.
func (,  string) Attribute {
	return Attribute{
		Key:   ,
		Value: ,
	}
}

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

func ( Attribute) ( []byte) []byte {
	 = append(, .Key...)
	if len(.Value) > 0 {
		 = append(append(, ':'), .Value...)
	}

	return 
}

func ( Attribute) () ( int) {
	 = len(.Key)
	if len(.Value) > 0 {
		 += 1 + len(.Value)
	}

	return 
}

// IsICECandidate returns true if the attribute key equals "candidate".
func ( Attribute) () bool {
	return .Key == "candidate"
}