// Code generated by go-uaa/generator; DO NOT EDIT.

package uaa

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"net/http"
	"net/url"
	"strconv"
)

// GetGroup with the given groupID.
func (a *API) GetGroup(groupID string) (*Group, error) {
	u := urlWithPath(*a.TargetURL, fmt.Sprintf("%s/%s", GroupsEndpoint, groupID))
	group := &Group{}
	err := a.doJSON(http.MethodGet, &u, nil, group, true)
	if err != nil {
		return nil, err
	}
	return group, nil
}

// CreateGroup creates the given group.
func (a *API) CreateGroup(group Group) (*Group, error) {
	u := urlWithPath(*a.TargetURL, GroupsEndpoint)
	created := &Group{}
	j, err := json.Marshal(group)
	if err != nil {
		return nil, err
	}
	err = a.doJSON(http.MethodPost, &u, bytes.NewBuffer([]byte(j)), created, true)
	if err != nil {
		return nil, err
	}
	return created, nil
}

// UpdateGroup updates the given group.
func (a *API) UpdateGroup(group Group) (*Group, error) {
	u := urlWithPath(*a.TargetURL, fmt.Sprintf("%s/%s", GroupsEndpoint, group.Identifier()))

	created := &Group{}
	j, err := json.Marshal(group)
	if err != nil {
		return nil, err
	}
	err = a.doJSON(http.MethodPut, &u, bytes.NewBuffer([]byte(j)), created, true)
	if err != nil {
		return nil, err
	}
	return created, nil
}

// DeleteGroup deletes the group with the given group ID.
func (a *API) DeleteGroup(groupID string) (*Group, error) {
	if groupID == "" {
		return nil, errors.New("groupID cannot be blank")
	}
	u := urlWithPath(*a.TargetURL, fmt.Sprintf("%s/%s", GroupsEndpoint, groupID))
	deleted := &Group{}
	err := a.doJSON(http.MethodDelete, &u, nil, deleted, true)
	if err != nil {
		return nil, err
	}
	return deleted, nil
}

// ListGroups with the given filter, sortBy, attributes, sortOrder, startIndex
// (1-based), and count (default 100).
// If successful, ListGroups returns the groups and the total itemsPerPage of groups for
// all pages. If unsuccessful, ListGroups returns the error.
func (a *API) ListGroups(filter string, sortBy string, attributes string, sortOrder SortOrder, startIndex int, itemsPerPage int) ([]Group, Page, error) {
	u := urlWithPath(*a.TargetURL, GroupsEndpoint)
	query := url.Values{}
	if filter != "" {
		query.Set("filter", filter)
	}
	if attributes != "" {
		query.Set("attributes", attributes)
	}
	if sortBy != "" {
		query.Set("sortBy", sortBy)
	}
	if sortOrder != "" {
		query.Set("sortOrder", string(sortOrder))
	}
	if startIndex == 0 {
		startIndex = 1
	}
	query.Set("startIndex", strconv.Itoa(startIndex))
	if itemsPerPage == 0 {
		itemsPerPage = 100
	}
	query.Set("count", strconv.Itoa(itemsPerPage))
	u.RawQuery = query.Encode()

	groups := &paginatedGroupList{}
	err := a.doJSON(http.MethodGet, &u, nil, groups, true)
	if err != nil {
		return nil, Page{}, err
	}
	page := Page{
		StartIndex:   groups.StartIndex,
		ItemsPerPage: groups.ItemsPerPage,
		TotalResults: groups.TotalResults,
	}
	return groups.Resources, page, err
}

// ListAllGroups retrieves UAA groups
func (a *API) ListAllGroups(filter string, sortBy string, attributes string, sortOrder SortOrder) ([]Group, error) {
	page := Page{
		StartIndex:   1,
		ItemsPerPage: 100,
	}
	var (
		results     []Group
		currentPage []Group
		err         error
	)

	for {
		currentPage, page, err = a.ListGroups(filter, sortBy, attributes, sortOrder, page.StartIndex, page.ItemsPerPage)
		if err != nil {
			return nil, err
		}
		results = append(results, currentPage...)

		if (page.StartIndex + page.ItemsPerPage) > page.TotalResults {
			break
		}
		page.StartIndex = page.StartIndex + page.ItemsPerPage
	}
	return results, nil
}
