diff --git a/agt/ballotagent/new_ballot.go b/agt/ballotagent/new_ballot.go index d8752e87643669875f472ebc0c05e43de4fd832f..0dfd83577f60de9a525bf9e4420bd304f9114e18 100644 --- a/agt/ballotagent/new_ballot.go +++ b/agt/ballotagent/new_ballot.go @@ -4,15 +4,18 @@ import ( "encoding/json" "fmt" "net/http" + "time" rad "gitlab.utc.fr/gvandevi/ia04binome2a" cs "gitlab.utc.fr/gvandevi/ia04binome2a/comsoc" ) type BallotInfo struct { - profile cs.Profile - isOpen bool - results rad.ResultResponse + profile cs.Profile + votersId []string + nbAlts int + isOpen bool + results rad.ResultResponse } func (rsa *BallotServerAgent) createBallot(w http.ResponseWriter, r *http.Request) { @@ -33,24 +36,45 @@ func (rsa *BallotServerAgent) createBallot(w http.ResponseWriter, r *http.Reques fmt.Fprint(w, err.Error()) return } + // Check for valid deadline formatting + deadline, errTime := time.Parse(time.RFC3339, req.Deadline) + if errTime != nil { + w.WriteHeader(http.StatusBadRequest) + msg := fmt.Sprintf("'%s' n'utilise pas le bon format, merci d'utiliser RFC3339 ", req.Deadline) + w.Write([]byte(msg)) + return + } + // Check if the deadline is in the future + if deadline.Before(time.Now()) { + w.WriteHeader(http.StatusBadRequest) + msg := fmt.Sprintf("'%s' est déjà passé ", req.Deadline) + w.Write([]byte(msg)) + return + } // traitement de la requête var resp rad.Ballot resp.BallotID = fmt.Sprintf("scrutin%d", len(rsa.ballots)+1) rsa.ballots[resp] = BallotInfo{ - profile: make(cs.Profile, 0), - isOpen: true, - results: rad.ResultResponse{}} + profile: make(cs.Profile, 0), + votersId: req.VotersID, + nbAlts: req.NbAlts, + isOpen: true, + results: rad.ResultResponse{}} + + tb := make([]cs.Alternative, 0) + for _, alt := range req.TieBreak { + tb = append(tb, cs.Alternative(alt)) + } switch req.Rule { case "majority": - + go rsa.handleBallot(resp, cs.MajoritySWF, cs.MajoritySCF, tb, deadline) case "borda": - - case "approval": - - case "stv": + go rsa.handleBallot(resp, cs.BordaSWF, cs.BordaSCF, tb, deadline) + //case "approval": + // go rsa.handleBallot(resp, cs.ApprovalSWF, cs.ApprovalSCF, tb, deadline) default: w.WriteHeader(http.StatusNotImplemented) msg := fmt.Sprintf("Unkonwn rule '%s'", req.Rule) @@ -62,3 +86,40 @@ func (rsa *BallotServerAgent) createBallot(w http.ResponseWriter, r *http.Reques serial, _ := json.Marshal(resp) w.Write(serial) } + +func (rsa *BallotServerAgent) handleBallot( + ballot rad.Ballot, + swf func(cs.Profile) (cs.Count, error), + scf func(cs.Profile) ([]cs.Alternative, error), + orderedTBAlts []cs.Alternative, + deadline time.Time, +) { + targetBallot := rsa.ballots[ballot] + fmt.Println(targetBallot) + time.Sleep(time.Until(deadline)) + targetBallot.isOpen = false + profile := targetBallot.profile + + // If profile is empty, set winner as 0 and ranking as empty list + if len(profile) == 0 { + targetBallot.results = rad.ResultResponse{Winner: 0, Ranking: make([]int, 0)} + fmt.Println(ballot.BallotID, "n'a pas reçu de votes.") + return + } + + tb := cs.TieBreakFactory(orderedTBAlts) + ballotSWF := cs.SWFFactory(swf, tb) + ballotSCF := cs.SCFFactory(scf, tb) + ranking, _ := ballotSWF(profile) + winner, err := ballotSCF(profile) + if err != nil { + fmt.Println(err) + return + } + intRanking := make([]int, 0) + for _, alt := range ranking { + intRanking = append(intRanking, int(alt)) + } + targetBallot.results = rad.ResultResponse{Winner: int(winner), Ranking: intRanking} + fmt.Println(targetBallot) +}