package emapi import ( "context" "fmt" "net/http" "go.infratographer.com/x/gidx" "go.equinixmetal.net/infra9-metal-bridge/internal/metal/models" ) const ( projectsPath = "/projects" ) // Projects contains a list of projects. type Projects []*Project // ToDetails converts the objects to generic project details. func (p Projects) ToDetails() []*models.ProjectDetails { projects := make([]*models.ProjectDetails, len(p)) var nextIndex int for _, project := range p { projects[nextIndex] = project.ToDetails() if projects[nextIndex] != nil { nextIndex++ } } if nextIndex < len(p) { return projects[:nextIndex] } return projects } // Project contains project information. type Project struct { client *Client HREF string `json:"href"` ID string `json:"id"` Name string `json:"name"` Description string `json:"description"` Memberships Memberships `json:"memberships"` Organization *Organization `json:"organization"` } // ToDetails converts the project to generic project details. func (p *Project) ToDetails() *models.ProjectDetails { var id string if p != nil { id = idOrLinkID(p.ID, p.HREF) } if id == "" { return nil } details := &models.ProjectDetails{ ID: id, Name: p.Name, Organization: p.Organization.ToDetails(), } details.Memberships = p.Memberships.ToDetailsWithProjectDetails(details) return details } // getProjectWithMemberships fetches the provided project with membership information. func (c *Client) getProjectWithMemberships(ctx context.Context, id string) (*Project, error) { var project Project _, err := c.DoRequest(ctx, http.MethodGet, projectsPath+"/"+id+"?include=memberships.user", nil, &project) if err != nil { return nil, fmt.Errorf("error loading organization: %w", err) } return &project, nil } // GetProjectDetails fetchs the provided project id with membership information. func (c *Client) GetProjectDetails(ctx context.Context, id gidx.PrefixedID) (*models.ProjectDetails, error) { project, err := c.getProjectWithMemberships(ctx, id.String()[gidx.PrefixPartLength+1:]) if err != nil { return nil, err } return project.ToDetails(), nil }