package gophercloud

import (
	"errors"

	"github.com/racker/perigee"
)

var (
	// ErrPageNotAvailable is returned from a Pager when a next or previous page is requested, but does not exist.
	ErrPageNotAvailable = errors.New("The requested Collection page does not exist.")
)

// Collection describes the minimum functionality that any collection resource must implement to be able to use
// the global paging and iteration functions.
// Every resource that returns a list of multiple results must implement this functionality, whether or not it is paged.
// In addition to the methods provided here, each collection should also provide an AsItem(Page) method that
// casts the Page to its more specific type and returns the Page's contents as a slice.
type Collection interface {

	// Pager returns one of the concrete Pager implementations from this package, or a custom one.
	// The style of Pager returned determines how the collection is paged.
	Pager() Pager
}

// EachPage iterates through a Collection one page at a time.
// The handler function will be invoked with a Collection containing each page.
// If the handler returns true, iteration will continue. If it returns false, no more pages will be fetched.
func EachPage(first Collection, handler func(Collection) bool) error {
	p := first.Pager()
	var err error
	current := first

	for {
		if !handler(current) {
			return nil
		}

		if !p.HasNextPage() {
			return nil
		}

		current, err = p.NextPage()
		if err != nil {
			return err
		}
	}
}

// AllPages consolidates all pages reachable from a provided starting point into a single mega-Page.
// Use this only when you know that the full set will always fit within memory.
func AllPages(first Collection) (Collection, error) {
	return first, nil
}

// Pager describes a specific paging idiom for a Page resource.
// Generally, to use a Pager, the Page must also implement a more specialized interface than Page.
// Clients should not generally interact with Pagers directly.
// Instead, use the more convenient collection traversal methods: All and EachPage.
type Pager interface {

	// HasNextPage returns true if a call to NextPage will return an additional Page of results.
	HasNextPage() bool

	// NextPage returns the next Page in the sequence.
	// Panics if no page is available, so always check HasNextPage first.
	NextPage() (Collection, error)
}

// SinglePager is used by collections that are not actually paged.
// It has no additional interface requirements for its host Page.
type SinglePager struct{}

// HasNextPage always reports false.
func (p SinglePager) HasNextPage() bool {
	return false
}

// NextPage always returns an ErrPageNotAvailable.
func (p SinglePager) NextPage() (Collection, error) {
	return nil, ErrPageNotAvailable
}

// PaginationLinks stores the `next` and `previous` links that are provided by some (but not all) paginated resources.
type PaginationLinks struct {

	// Next is the full URL to the next page of results, or nil if this is the last page.
	Next *string `json:"next,omitempty"`

	// Previous is the full URL to the previous page of results, or nil if this is the first page.
	Previous *string `json:"previous,omitempty"`
}

// LinkCollection must be satisfied by a Page that uses a LinkPager.
type LinkCollection interface {

	// Pager is specified here so every LinkCollection will also be a valid Page.
	Pager() Pager

	// Service returns the client used to make further requests.
	Service() *ServiceClient

	// Links returns the pagination links from a single page.
	Links() PaginationLinks

	// Interpret an arbitrary JSON result as a new LinkCollection.
	Interpret(interface{}) (LinkCollection, error)
}

// LinkPager implements paging for collections that provide a link structure in their response JSON.
// It follows explicit `next` links and stops when the `next` link is "null".
type LinkPager struct {
	current LinkCollection
}

// NewLinkPager creates and initializes a pager for a LinkCollection.
func NewLinkPager(first LinkCollection) *LinkPager {
	return &LinkPager{current: first}
}

// HasNextPage checks the `next` link in the pagination data.
func (p *LinkPager) HasNextPage() bool {
	return p.current.Links().Next != nil
}

// NextPage follows the `next` link to construct the next page of data.
func (p *LinkPager) NextPage() (Collection, error) {
	url := p.current.Links().Next
	if url == nil {
		return nil, ErrPageNotAvailable
	}

	var response interface{}
	_, err := perigee.Request("GET", *url, perigee.Options{
		MoreHeaders: p.current.Service().Provider.AuthenticatedHeaders(),
		Results:     &response,
		OkCodes:     []int{200},
	})
	if err != nil {
		return nil, err
	}

	interpreted, err := p.current.Interpret(response)
	if err != nil {
		return nil, err
	}

	p.current = interpreted
	return interpreted, nil
}
