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

package extension

import (
	
)

// ALPN is a TLS extension for application-layer protocol negotiation within
// the TLS handshake.
//
// https://tools.ietf.org/html/rfc7301
type ALPN struct {
	ProtocolNameList []string
}

// TypeValue returns the extension TypeValue
func ( ALPN) () TypeValue {
	return ALPNTypeValue
}

// Marshal encodes the extension
func ( *ALPN) () ([]byte, error) {
	var  cryptobyte.Builder
	.AddUint16(uint16(.TypeValue()))
	.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
		.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
			for ,  := range .ProtocolNameList {
				 :=  // Satisfy range scope lint
				.AddUint8LengthPrefixed(func( *cryptobyte.Builder) {
					.AddBytes([]byte())
				})
			}
		})
	})
	return .Bytes()
}

// Unmarshal populates the extension from encoded data
func ( *ALPN) ( []byte) error {
	 := cryptobyte.String()

	var  uint16
	.ReadUint16(&)
	if TypeValue() != .TypeValue() {
		return errInvalidExtensionType
	}

	var  cryptobyte.String
	.ReadUint16LengthPrefixed(&)

	var  cryptobyte.String
	if !.ReadUint16LengthPrefixed(&) || .Empty() {
		return ErrALPNInvalidFormat
	}
	for !.Empty() {
		var  cryptobyte.String
		if !.ReadUint8LengthPrefixed(&) || .Empty() {
			return ErrALPNInvalidFormat
		}
		.ProtocolNameList = append(.ProtocolNameList, string())
	}
	return nil
}

// ALPNProtocolSelection negotiates a shared protocol according to #3.2 of rfc7301
func (,  []string) (string, error) {
	if len() == 0 || len() == 0 {
		return "", nil
	}
	for ,  := range  {
		for ,  := range  {
			if  ==  {
				return , nil
			}
		}
	}
	return "", errALPNNoAppProto
}