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

package ice

import (
	

	
	
	
	
	
	
)

// MulticastDNSMode represents the different Multicast modes ICE can run in.
type MulticastDNSMode byte

// MulticastDNSMode enum.
const (
	// MulticastDNSModeDisabled means remote mDNS candidates will be discarded, and local host candidates will use IPs.
	MulticastDNSModeDisabled MulticastDNSMode = iota + 1

	// MulticastDNSModeQueryOnly means remote mDNS candidates will be accepted, and local host candidates will use IPs.
	MulticastDNSModeQueryOnly

	// MulticastDNSModeQueryAndGather means remote mDNS candidates will be accepted,
	// and local host candidates will use mDNS.
	MulticastDNSModeQueryAndGather
)

func generateMulticastDNSName() (string, error) {
	// https://tools.ietf.org/id/draft-ietf-rtcweb-mdns-ice-candidates-02.html#gathering
	// The unique name MUST consist of a version 4 UUID as defined in [RFC4122], followed by “.local”.
	,  := uuid.NewRandom()

	return .String() + ".local", 
}

//nolint:cyclop
func createMulticastDNS(
	 transport.Net,
	 []NetworkType,
	 []*transport.Interface,
	 bool,
	 MulticastDNSMode,
	 string,
	 logging.LeveledLogger,
	 logging.LoggerFactory,
) (*mdns.Conn, MulticastDNSMode, error) {
	if  == MulticastDNSModeDisabled {
		return nil, , nil
	}

	var ,  bool
	if len() == 0 {
		 = true
		 = true
	} else {
		for ,  := range  {
			if .IsIPv4() {
				 = true

				continue
			}
			if .IsIPv6() {
				 = true
			}
		}
	}

	,  := .ResolveUDPAddr("udp4", mdns.DefaultAddressIPv4)
	if  != nil {
		return nil, , 
	}
	,  := .ResolveUDPAddr("udp6", mdns.DefaultAddressIPv6)
	if  != nil {
		return nil, , 
	}

	var  *ipv4.PacketConn
	var  error
	if  {
		var  transport.UDPConn
		,  = .ListenUDP("udp4", )
		if  != nil {
			// If ICE fails to start MulticastDNS server just warn the user and continue
			.Errorf("Failed to enable mDNS over IPv4: (%s)", )

			return nil, MulticastDNSModeDisabled, nil
		}
		 = ipv4.NewPacketConn()
	}

	var  *ipv6.PacketConn
	var  error
	if  {
		var  transport.UDPConn
		,  = .ListenUDP("udp6", )
		if  != nil {
			.Errorf("Failed to enable mDNS over IPv6: (%s)", )

			return nil, MulticastDNSModeDisabled, nil
		}
		 = ipv6.NewPacketConn()
	}

	if  != nil &&  != nil {
		// If ICE fails to start MulticastDNS server just warn the user and continue
		.Errorf("Failed to enable mDNS, continuing in mDNS disabled mode")
		//nolint:nilerr
		return nil, MulticastDNSModeDisabled, nil
	}
	var  []net.Interface
	if  != nil {
		 = make([]net.Interface, 0, len())
		for ,  := range  {
			 = append(, .Interface)
		}
	}

	switch  {
	case MulticastDNSModeQueryOnly:
		,  := mdns.Server(, , &mdns.Config{
			Interfaces:      ,
			IncludeLoopback: ,
			LoggerFactory:   ,
		})

		return , , 
	case MulticastDNSModeQueryAndGather:
		,  := mdns.Server(, , &mdns.Config{
			Interfaces:      ,
			IncludeLoopback: ,
			LocalNames:      []string{},
			LoggerFactory:   ,
		})

		return , , 
	default:
		return nil, , nil
	}
}