package comsoc
import("fmt")
 
func TieBreakFactory(orderedAlts []Alternative) (func ([]Alternative) (Alternative, error)){
		return func (bestAlts []Alternative) (Alternative, error) {
			bestAlt := bestAlts[0]
			for _,alt:= range bestAlts[1:]{
				if isPref(alt,bestAlt,orderedAlts){
					bestAlt = alt
				}
			}
			return bestAlt, nil
		}
}

func Test_tieBreakFactory(){
	orderedAlts := []Alternative{8,9,6,1,3,2}
	fmt.Println("Ordre strict :", orderedAlts)
	lambda:=TieBreakFactory(orderedAlts)
	bestAlts := []Alternative{3,6}
	fmt.Println("Premières alternatives, à départager :", bestAlts)
	bestAlt,_ := lambda(bestAlts)
	fmt.Println("Première alternative :", bestAlt)
}

func SWFFactory(swf func (Profile) (Count, error), tb func([]Alternative) (Alternative, error)) (func(Profile) ([]Alternative, error)){
	
	return func(p Profile) ([]Alternative, error){
		//récupération du décompte
		count,_ := swf(p)
		//préparation de la sortie
		var sorted_alts []Alternative

		//PARCOURS DU DECOMPTE
		for len(count) > 0{
			//On prend les meilleures alternatives (avant tie break)
			bestAlts := maxCount(count)
			//On supprime les meilleures alternatives du décompte
			for alt := range bestAlts{
			delete(count, Alternative(alt))
			}
		//Départage
			for len(bestAlts) > 0{
				bestAlt,_ := tb(bestAlts)
				//ajout de la meilleure alternative post-tie break
				sorted_alts = append(sorted_alts, bestAlt)
				//suppression de l'alternative dans bestAlts
				indice := rank(bestAlt, bestAlts)
				bestAlts=append(bestAlts[:indice], bestAlts[indice+1:]...)
				//suppression de l'alternativ dans le compte 
				delete(count, Alternative(bestAlt))
				}
			}
			return sorted_alts,nil
		}
}

func Test_sWFFactory(){
	//Définition de l'Ordre strict
	orderedAlts := []Alternative{8,9,6,1,3,2}
	fmt.Println("Ordre strict :", orderedAlts)

	//Construction d'un profil avec alternatives ex aequo
	profil := make([][]Alternative, 2)
	profil[0] = []Alternative{1, 2, 3,4,5,6}
	profil[1] = []Alternative{3, 2, 1,4,5,6}
	fmt.Println("Profil :", profil)

	//Construction de la fonction Tie Break
	lambda:=TieBreakFactory(orderedAlts)
	//Construction de la Social Welfare Factory à partir de la fonction swf + la fonction de TieBreak
	mu := SWFFactory(BordaSWF,lambda)
	//Construction d'une fonction 
	sorted_alts,_ := mu(profil)
	fmt.Println("Alternatives strictement ordonnées selon la méthode de Borda :", sorted_alts)
}
//func SCFFactory(func scf(p Profile) ([]Alternative, error), func ([]Alternative) (Alternative, error)) (func(Profile) (Alternative, error))