package web
import (
"net/http"
"net/url"
"slices"
"craftdesign.group/quarry/internal/index"
"craftdesign.group/quarry/internal/ops"
)
// stackCandidate is an open landing another may be stacked on.
type stackCandidate struct {
ID string
Number int
Title string
Branch string
}
// stackCandidates lists the open landings the landing id (on branch,
// aimed at target) may be stacked on: newest activity first, never
// itself or what it already targets, and never one whose strata already
// stands on it, which would make a loop. The op refuses those too; the
// list is so the page never offers what it would refuse.
func stackCandidates(req *http.Request, r *ops.Registry, repo, id, branch, target string) []stackCandidate {
res, err := invoke(req.Context(), r, "landing.list", url.Values{
"repo": {repo}, "state": {"open"}, "limit": {"200"}})
if err != nil {
return nil
}
var list struct {
Landings []index.LandingSummary `json:"landings"`
}
remarshal(res, &list)
var out []stackCandidate
for _, l := range list.Landings {
if l.ID == id || l.State != "open" || l.SupersededBy != "" || l.Branch == target || l.Branch == branch {
continue
}
if _, through, ok := index.LandsOn(list.Landings, l.Branch); !ok || slices.Contains(through, branch) {
continue
}
out = append(out, stackCandidate{ID: l.ID, Number: l.Number, Title: l.Title, Branch: l.Branch})
}
return out
}