package comsoc

import (
	"errors"
)

func TieBreakFactory(tieBreakAlts []Alternative) func([]Alternative) (Alternative, error) {
	return func(alts []Alternative) (Alternative, error) {	// alts est la liste de candidats ex-aequo
		if len(alts) == 0 || alts == nil {
			return -1, errors.New("002: NullAlternatives")
		}

		for _, tieBreakAlt := range tieBreakAlts {
			for _, alt := range alts {
				if alt == tieBreakAlt {
					return alt, nil
				}
			}
		}

		return -1, errors.New("002: NoTieBreakAlternativeFound")
	}
}

func SWFFactory(swf1 func (Profile) (Count, error), tieBreak func ([]Alternative) (Alternative, error)) (swf2 func(Profile) (alts []Alternative, err error)) {
 return func(p Profile) (alts []Alternative, err error) {

   count, _ := swf1(p)
	// winner := -1
	 for count != nil {			// on cherche les maxcount
			bestAlts := maxCount(count)

			for len(bestAlts) > 1 {		// tant qu'on a pas départagé les exaequos
				winner,_ := tieBreak(bestAlts)
				for i, alt := range bestAlts {		// départage de tous les exaequos
					if alt == winner {
						delete(count, winner)
						alts = append(alts, winner)
						bestAlts = append(bestAlts[:i], bestAlts[i+1:]...)
						break
					}
				}
			}
			alts = append(alts, bestAlts[0])
			delete(count,bestAlts[0])

			// au cas où, une autre ébauche
			// 						# on prend la ou les BestAlts du count
			// for i,bestAlt := range(bestAlts) {		#
			// 	winner, _ := tieBreak(bestAlts)
			// 	for j,bestAltToDelete := range(bestAlts)
			// 	if besAltToDelete == winner {
			// 		keys[i] = -1			# on exclue le winner de la slice pour le prochain tie break
			// 		alts = append(alts, winner)
			// 		break
			// 	}
			// }
	 }

	 return alts, nil
  }
}

func SCFFactory(scf1 func(Profile) ([]Alternative, error), tieBreak func([]Alternative) (Alternative, error)) (scf2 func(Profile) (alt Alternative, err error)) {
	return func(p Profile) (Alternative, error) {
		alts, errSCF1 := scf1(p)
		if errSCF1 != nil {
			return -1, errSCF1
		}
		alt, errTB := tieBreak(alts)
		if errTB != nil {
			return -1, errTB
		}

		return alt, nil
	}
}

// func TieBreak(a []Alternative) (Alternative, err error) {
//   // if len(a) == 0 || a == nil {
//   //   return _, errors.New("002: NullAlternatives")
//   // }
//   // for _,alt := range a {
//   //
//   // }                       // 0-votes alternatives are not included
//   // return nil, nil
// }