// Copyright 2022 uTLS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package tls

import (
	
)

// Only implemented client-side, for server certificates.
// Alternate certificate message formats (https://datatracker.ietf.org/doc/html/rfc7250) are not
// supported.
// https://datatracker.ietf.org/doc/html/rfc8879
type utlsCompressedCertificateMsg struct {
	raw []byte

	algorithm                    uint16
	uncompressedLength           uint32 // uint24
	compressedCertificateMessage []byte
}

func ( *utlsCompressedCertificateMsg) () ([]byte, error) {
	if .raw != nil {
		return .raw, nil
	}

	var  cryptobyte.Builder
	.AddUint8(utlsTypeCompressedCertificate)
	.AddUint24LengthPrefixed(func( *cryptobyte.Builder) {
		.AddUint16(.algorithm)
		.AddUint24(.uncompressedLength)
		.AddUint24LengthPrefixed(func( *cryptobyte.Builder) {
			.AddBytes(.compressedCertificateMessage)
		})
	})

	var  error
	.raw,  = .Bytes()
	return .raw, 
}

func ( *utlsCompressedCertificateMsg) ( []byte) bool {
	* = utlsCompressedCertificateMsg{raw: }
	 := cryptobyte.String()

	if !.Skip(4) || // message type and uint24 length field
		!.ReadUint16(&.algorithm) ||
		!.ReadUint24(&.uncompressedLength) ||
		!readUint24LengthPrefixed(&, &.compressedCertificateMessage) {
		return false
	}
	return true
}

type utlsEncryptedExtensionsMsgExtraFields struct {
	applicationSettings          []byte
	applicationSettingsCodepoint uint16
	customExtension              []byte
}

func ( *encryptedExtensionsMsg) ( uint16,  cryptobyte.String) bool {
	switch  {
	case utlsExtensionApplicationSettings:
		fallthrough
	case utlsExtensionApplicationSettingsNew:
		.utls.applicationSettingsCodepoint = 
		.utls.applicationSettings = []byte()
	}
	return true // success/unknown extension
}

type utlsClientEncryptedExtensionsMsg struct {
	raw                          []byte
	applicationSettings          []byte
	applicationSettingsCodepoint uint16
	customExtension              []byte
}

func ( *utlsClientEncryptedExtensionsMsg) () ( []byte,  error) {
	if .raw != nil {
		return .raw, nil
	}

	var  cryptobyte.Builder
	.AddUint8(typeEncryptedExtensions)
	.AddUint24LengthPrefixed(func( *cryptobyte.Builder) {
		.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
			if .applicationSettingsCodepoint != 0 {
				.AddUint16(.applicationSettingsCodepoint)
				.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
					.AddBytes(.applicationSettings)
				})
			}
			if len(.customExtension) > 0 {
				.AddUint16(utlsFakeExtensionCustom)
				.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
					.AddBytes(.customExtension)
				})
			}
		})
	})

	.raw,  = .Bytes()
	return .raw, 
}

func ( *utlsClientEncryptedExtensionsMsg) ( []byte) bool {
	* = utlsClientEncryptedExtensionsMsg{raw: }
	 := cryptobyte.String()

	var  cryptobyte.String
	if !.Skip(4) || // message type and uint24 length field
		!.ReadUint16LengthPrefixed(&) || !.Empty() {
		return false
	}

	for !.Empty() {
		var  uint16
		var  cryptobyte.String
		if !.ReadUint16(&) ||
			!.ReadUint16LengthPrefixed(&) {
			return false
		}

		switch  {
		case utlsExtensionApplicationSettings:
			fallthrough
		case utlsExtensionApplicationSettingsNew:
			.applicationSettingsCodepoint = 
			.applicationSettings = []byte()
		default:
			// Unknown extensions are illegal in EncryptedExtensions.
			return false
		}
	}
	return true
}