package dnsutils

import (
	
	
	
)

// OrderedSRV returns a count of the results and a map keyed on the order they should be used.
// This based on the records' priority and randomised selection based on their relative weighting.
// The function's inputs are the same as those for net.LookupSRV
// To use in the correct order:
//
// count, orderedSRV, err := OrderedSRV(service, proto, name)
// i := 1
// for  i <= count {
//   srv := orderedSRV[i]
//   // Do something such as dial this SRV. If fails move on the the next or break if it succeeds.
//   i += 1
// }
func (, ,  string) (int, map[int]*net.SRV, error) {
	, ,  := net.LookupSRV(, , )
	if  != nil {
		return 0, make(map[int]*net.SRV), 
	}
	,  := orderSRV()
	return , , nil
}

func orderSRV( []*net.SRV) (int, map[int]*net.SRV) {
	// Initialise the ordered map
	var  int
	 := make(map[int]*net.SRV)

	 := make(map[int][]*net.SRV, 0)
	for ,  := range  {
		[int(.Priority)] = append([int(.Priority)], )
	}

	 := make([]int, 0)
	for  := range  {
		 = append(, )
	}

	var  int
	sort.Ints()
	for ,  := range  {
		 := weightedOrder([])
		for ,  := range  {
			 += 1
			[+] = 
		}
		 += len()
	}
	return , 
}

func weightedOrder( []*net.SRV) map[int]*net.SRV {
	// Get the total weight
	var  int
	for ,  := range  {
		 += int(.Weight)
	}

	// Initialise the ordered map
	 := 1
	 := make(map[int]*net.SRV)

	// Whilst there are still entries to be ordered
	 := len()
	for  > 0 {
		 := rand.Intn()
		 := []
		var  int
		if  > 0 {
			// Greater the weight the more likely this will be zero or less
			 = rand.Intn() - int(.Weight)
		}
		if  <= 0 {
			// Put entry in position
			[] = 
			if len() > 1 {
				// Remove the entry from the source slice by swapping with the last entry and truncating
				[len()-1], [] = [], [len()-1]
				 = [:len()-1]
				 = len()
			} else {
				 = 0
			}
			 += 1
			 =  - int(.Weight)
		}
	}
	return 
}