package resolution import ( "fmt" "sort" mcat "git.novox.be/novox/mesh-sdk/go/catalogue" ) // SeatsToPassOn reads the mesh for seats held once whose holder on record has left (novox/hq ADR 0449 §4). // // **A holder on record that is assigned on no machine holds nothing, and a seat that answers nothing is // the day a delivery removed its module.** Of such a seat, exactly one assignment in the mesh able to hold // it (it claims the seat at its scope and CanHold accepts it) takes it over: that is a pass, and the caller // records it and writes the hand act. With no such assignment the record stays; with two or more nothing is // recorded and the answer says so, naming both and the `seat --to` that settles it. A holder still assigned // anywhere changes nothing: the other claimants stand beside it, eligible and silent (ADR 0131). Only mesh // seats held once are read: a replicated seat's holders are added by an act (ADR 0223), a kinded bench is held // by its claims, and a seat with several holders on record is a store that disagrees with the mesh (refused // by the resolver). func SeatsToPassOn(holdings []mcat.Held, assignments []mcat.Assignment) ([]mcat.SeatPass, []string) { assigned := map[string]bool{} for _, a := range assignments { assigned[a.Manifest.Module] = true } bySeat := map[string][]mcat.Held{} var order []string for _, h := range holdings { s, ok := mcat.SeatNamed(h.Claim) if !ok || s.Replicated || s.Scope != mcat.ScopeMesh || h.Scope != mcat.ScopeMesh || mcat.KindedBenches[s.Name] { continue } if _, seen := bySeat[s.Name]; !seen { order = append(order, s.Name) } bySeat[s.Name] = append(bySeat[s.Name], h) } sort.Strings(order) var passes []mcat.SeatPass var said []string for _, name := range order { recs := bySeat[name] if len(recs) != 1 || assigned[recs[0].Module] { continue } seat, _ := mcat.SeatNamed(name) var claimants []mcat.Held for _, a := range assignments { if mcat.CanHold(a.Manifest, seat) != nil { continue } claimants = append(claimants, mcat.Held{Claim: seat.Name, Scope: seat.Scope, Node: a.Node, Module: a.Manifest.Module}) } sort.Slice(claimants, func(i, j int) bool { if claimants[i].Node != claimants[j].Node { return claimants[i].Node < claimants[j].Node } return claimants[i].Module < claimants[j].Module }) switch len(claimants) { case 0: case 1: passes = append(passes, mcat.SeatPass{Seat: seat, From: recs[0], To: claimants[0]}) default: said = append(said, fmt.Sprintf( "%s on %s is on record as the holder of %q and is assigned nowhere, and %s on %s and %s on %s both claim it "+ "— nothing is recorded; `seat %s --to /` records the one that holds it", recs[0].Module, recs[0].Node, seat.Name, claimants[0].Module, claimants[0].Node, claimants[1].Module, claimants[1].Node, seat.Name)) } } return passes, said }