// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package frontend

import (
	"net/http"
	"net/url"
	"strconv"

	"golang.org/x/pkgsite/internal/log"
)

// pagination holds information related to paginated display. It is intended to
// be part of a view model struct.
//
// Given a sequence of results with offsets 0, 1, 2 ... (typically from a
// database query), we paginate it by dividing it into numbered pages
// 1, 2, 3, .... Each page except possibly the last has the same number of results.
type pagination struct {
	baseURL     *url.URL // URL common to all pages
	limit       int      // the maximum number of results on a page
	ResultCount int      // number of results on this page
	TotalCount  int      // total number of results
	Approximate bool     // whether or not the total count is approximate
	Page        int      // number of the current page
	PrevPage    int      //   "    "   "  previous page, usually Page-1 but zero if Page == 1
	NextPage    int      //   "    "   "  next page, usually Page+1, but zero on the last page
	Offset      int      // offset of the first item on the current page
	Pages       []int    // consecutive page numbers to be displayed for navigation
}

// PageURL constructs a URL that displays the given page.
// It adds a "page" query parameter to the base URL.
func (p pagination) PageURL(page int) string {
	newQuery := p.baseURL.Query()
	newQuery.Set("page", strconv.Itoa(page))
	p.baseURL.RawQuery = newQuery.Encode()
	return p.baseURL.String()
}

// newPagination constructs a pagination. Call it after some results have been
// obtained.
// resultCount is the number of results in the current page.
// totalCount is the total number of results.
func newPagination(params paginationParams, resultCount, totalCount int) pagination {
	return pagination{
		baseURL:     params.baseURL,
		TotalCount:  totalCount,
		ResultCount: resultCount,
		Offset:      params.offset(),
		limit:       params.limit,
		Page:        params.page,
		PrevPage:    prev(params.page),
		NextPage:    next(params.page, params.limit, totalCount),
		Pages:       pagesToLink(params.page, numPages(params.limit, totalCount), defaultNumPagesToLink),
	}
}

// paginationParams holds pagination parameters extracted from the request.
type paginationParams struct {
	baseURL *url.URL
	page    int // the number of the page to display
	limit   int // the maximum number of results to display on the page
}

// offset returns the offset of the first result on the page.
func (p paginationParams) offset() int {
	return offset(p.page, p.limit)
}

// newPaginationParams extracts pagination params from the request.
func newPaginationParams(r *http.Request, defaultLimit int) paginationParams {
	positiveParam := func(key string, dflt int) (val int) {
		var err error
		if a := r.FormValue(key); a != "" {
			val, err = strconv.Atoi(a)
			if err != nil {
				log.Errorf(r.Context(), "strconv.Atoi(%q) for page: %v", a, err)
			}
		}
		if val < 1 {
			val = dflt
		}
		return val
	}
	return paginationParams{
		baseURL: r.URL,
		page:    positiveParam("page", 1),
		limit:   positiveParam("limit", defaultLimit),
	}
}

const defaultNumPagesToLink = 5

// pagesToLink returns the page numbers that will be displayed. Given a
// page, it returns a slice containing numPagesToLink integers in ascending
// order and optimizes for page to be in the middle of that range. The max
// value of an integer in the return slice will be less than numPages.
func pagesToLink(page, numPages, numPagesToLink int) []int {
	var pages []int
	start := page - (numPagesToLink / 2)
	if (numPages - start) < numPagesToLink {
		start = numPages - numPagesToLink + 1
	}
	if start < 1 {
		start = 1
	}

	for i := start; (i < start+numPagesToLink) && (i <= numPages); i++ {
		pages = append(pages, i)
	}
	return pages
}

// numPages is the total number of pages needed to display all the results,
// given the specified maximum page size and the total number of results.
func numPages(pageSize, totalCount int) int {
	return (totalCount + pageSize - 1) / pageSize
}

// offset returns the offset of the first result on page, assuming all previous
// pages were of size limit.
func offset(page, limit int) int {
	if page <= 1 {
		return 0
	}
	return (page - 1) * limit
}

// prev returns the number of the page before the given page, or zero if the
// given page is 1 or smaller.
func prev(page int) int {
	if page <= 1 {
		return 0
	}
	return page - 1
}

// next returns the number of the page after the given page, or zero if page is is the last page or larger.
// limit and totalCount are used to calculate the last page (see numPages).
func next(page, limit, totalCount int) int {
	if page >= numPages(limit, totalCount) {
		return 0
	}
	return page + 1
}
