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

package dtls

import (
	
	

	
	
	
	
	
)

func flight0Parse( context.Context,  flightConn,  *State,  *handshakeCache,  *handshakeConfig) (flightVal, *alert.Alert, error) {
	, ,  := .fullPullMap(0, .cipherSuite,
		handshakeCachePullRule{handshake.TypeClientHello, .initialEpoch, true, false},
	)
	if ! {
		// No valid message received. Keep reading
		return 0, nil, nil
	}
	.handshakeRecvSequence = 

	var  *handshake.MessageClientHello

	// Validate type
	if ,  = [handshake.TypeClientHello].(*handshake.MessageClientHello); ! {
		return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, nil
	}

	if !.Version.Equal(protocol.Version1_2) {
		return 0, &alert.Alert{Level: alert.Fatal, Description: alert.ProtocolVersion}, errUnsupportedProtocolVersion
	}

	.remoteRandom = .Random

	 := []CipherSuite{}
	for ,  := range .CipherSuiteIDs {
		if  := cipherSuiteForID(CipherSuiteID(), .customCipherSuites);  != nil {
			 = append(, )
		}
	}

	if .cipherSuite,  = findMatchingCipherSuite(, .localCipherSuites); ! {
		return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InsufficientSecurity}, errCipherSuiteNoIntersection
	}

	for ,  := range .Extensions {
		switch e := .(type) {
		case *extension.SupportedEllipticCurves:
			if len(.EllipticCurves) == 0 {
				return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InsufficientSecurity}, errNoSupportedEllipticCurves
			}
			.namedCurve = .EllipticCurves[0]
		case *extension.UseSRTP:
			,  := findMatchingSRTPProfile(.ProtectionProfiles, .localSRTPProtectionProfiles)
			if ! {
				return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InsufficientSecurity}, errServerNoMatchingSRTPProfile
			}
			.setSRTPProtectionProfile()
		case *extension.UseExtendedMasterSecret:
			if .extendedMasterSecret != DisableExtendedMasterSecret {
				.extendedMasterSecret = true
			}
		case *extension.ServerName:
			.serverName = .ServerName // remote server name
		case *extension.ALPN:
			.peerSupportedProtocols = .ProtocolNameList
		}
	}

	if .extendedMasterSecret == RequireExtendedMasterSecret && !.extendedMasterSecret {
		return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InsufficientSecurity}, errServerRequiredButNoClientEMS
	}

	if .localKeypair == nil {
		var  error
		.localKeypair,  = elliptic.GenerateKeypair(.namedCurve)
		if  != nil {
			return 0, &alert.Alert{Level: alert.Fatal, Description: alert.IllegalParameter}, 
		}
	}

	 := flight2

	if .insecureSkipHelloVerify {
		 = flight4
	}

	return handleHelloResume(.SessionID, , , )
}

func handleHelloResume( []byte,  *State,  *handshakeConfig,  flightVal) (flightVal, *alert.Alert, error) {
	if len() > 0 && .sessionStore != nil {
		if ,  := .sessionStore.Get();  != nil {
			return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, 
		} else if .ID != nil {
			.log.Tracef("[handshake] resume session: %x", )

			.SessionID = 
			.masterSecret = .Secret

			if  := .initCipherSuite();  != nil {
				return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, 
			}

			 := .localRandom.MarshalFixed()
			.writeKeyLog(keyLogLabelTLS12, [:], .masterSecret)

			return flight4b, nil, nil
		}
	}
	return , nil, nil
}

func flight0Generate( flightConn,  *State,  *handshakeCache,  *handshakeConfig) ([]*packet, *alert.Alert, error) {
	// Initialize
	if !.insecureSkipHelloVerify {
		.cookie = make([]byte, cookieLength)
		if ,  := rand.Read(.cookie);  != nil {
			return nil, nil, 
		}
	}

	var  uint16
	.localEpoch.Store()
	.remoteEpoch.Store()
	.namedCurve = defaultNamedCurve

	if  := .localRandom.Populate();  != nil {
		return nil, nil, 
	}

	return nil, nil, nil
}