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

package extension

import (
	

	
)

const serverNameTypeDNSHostName = 0

// ServerName allows the client to inform the server the specific
// name it wishes to contact. Useful if multiple DNS names resolve
// to one IP
//
// https://tools.ietf.org/html/rfc6066#section-3
type ServerName struct {
	ServerName string
}

// TypeValue returns the extension TypeValue.
func ( ServerName) () TypeValue {
	return ServerNameTypeValue
}

// Marshal encodes the extension.
func ( *ServerName) () ([]byte, error) {
	var  cryptobyte.Builder
	.AddUint16(uint16(.TypeValue()))
	.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
		.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
			.AddUint8(serverNameTypeDNSHostName)
			.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
				.AddBytes([]byte(.ServerName))
			})
		})
	})

	return .Bytes()
}

// Unmarshal populates the extension from encoded data.
func ( *ServerName) ( []byte) error { //nolint:cyclop
	 := cryptobyte.String()
	var  uint16
	.ReadUint16(&)
	if TypeValue() != .TypeValue() {
		return errInvalidExtensionType
	}

	var  cryptobyte.String
	.ReadUint16LengthPrefixed(&)

	var  cryptobyte.String
	if !.ReadUint16LengthPrefixed(&) || .Empty() {
		return errInvalidSNIFormat
	}
	for !.Empty() {
		var  uint8
		var  cryptobyte.String
		if !.ReadUint8(&) ||
			!.ReadUint16LengthPrefixed(&) ||
			.Empty() {
			return errInvalidSNIFormat
		}
		if  != serverNameTypeDNSHostName {
			continue
		}
		if len(.ServerName) != 0 {
			// Multiple names of the same name_type are prohibited.
			return errInvalidSNIFormat
		}
		.ServerName = string()
		// An SNI value may not include a trailing dot.
		if strings.HasSuffix(.ServerName, ".") {
			return errInvalidSNIFormat
		}
	}

	return nil
}