// Copyright 2016 Google LLC.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package testing provides support functions for testing iterators conforming
// to the standard pattern.
// See package google.golang.org/api/iterator and
// https://github.com/GoogleCloudPlatform/gcloud-golang/wiki/Iterator-Guidelines.
package testing

import (
	"fmt"
	"reflect"

	"google.golang.org/api/iterator"
)

// TestIterator tests the Next method of a standard iterator. It assumes that
// the underlying sequence to be iterated over already exists.
//
// The want argument should be a slice that contains the elements of this
// sequence. It may be an empty slice, but it must not be the nil interface
// value. The elements must be comparable with reflect.DeepEqual.
//
// The create function should create and return a new iterator.
// It will typically look like
//
//	func() interface{} { return client.Items(ctx) }
//
// The next function takes the return value of create and should return the
// result of calling Next on the iterator. It can usually be defined as
//
//	func(it interface{}) (interface{}, error) { return it.(*ItemIterator).Next() }
//
// TestIterator checks that the iterator returns all the elements of want
// in order, followed by (zero, done). It also confirms that subsequent calls
// to next also return (zero, done).
//
// If the iterator implements the method
//
//	PageInfo() *iterator.PageInfo
//
// then exact pagination with iterator.Pager is also tested. Pagination testing
// will be more informative if the want slice contains at least three elements.
//
// On success, TestIterator returns ("", true). On failure, it returns a
// suitable error message and false.
func TestIterator(want interface{}, create func() interface{}, next func(interface{}) (interface{}, error)) (string, bool) {
	vWant := reflect.ValueOf(want)
	if vWant.Kind() != reflect.Slice {
		return "'want' must be a slice", false
	}
	it := create()
	msg, ok := testNext(vWant, it, next)
	if !ok {
		return msg, ok
	}
	if _, ok := it.(iterator.Pageable); !ok || vWant.Len() == 0 {
		return "", true
	}
	return testPaging(vWant, create, next)
}

// Check that the iterator returns vWant, the desired sequence.
func testNext(vWant reflect.Value, it interface{}, next func(interface{}) (interface{}, error)) (string, bool) {
	for i := 0; i < vWant.Len(); i++ {
		got, err := next(it)
		if err != nil {
			return fmt.Sprintf("#%d: got %v, expected an item", i, err), false
		}
		w := vWant.Index(i).Interface()
		if !reflect.DeepEqual(got, w) {
			return fmt.Sprintf("#%d: got %+v, want %+v", i, got, w), false
		}
	}
	// We now should see (<zero value of item type>, done), no matter how many
	// additional calls we make.
	zero := reflect.Zero(vWant.Type().Elem()).Interface()
	for i := 0; i < 3; i++ {
		got, err := next(it)
		if err != iterator.Done {
			return fmt.Sprintf("at end: got error %v, want iterator.Done", err), false
		}
		// Since err == iterator.Done, got should be zero.
		if got != zero {
			return fmt.Sprintf("got %+v with done, want zero %T", got, zero), false
		}
	}
	return "", true
}

// Test the iterator's behavior when used with iterator.Pager.
func testPaging(vWant reflect.Value, create func() interface{}, next func(interface{}) (interface{}, error)) (string, bool) {
	// Test page sizes that are smaller, equal to, and greater than the length
	// of the expected sequence.
	for _, pageSize := range []int{1, 2, vWant.Len(), vWant.Len() + 10} {
		wantPages := wantedPages(vWant, pageSize)
		// Test the Pager in two ways.
		// First, by creating a single Pager and calling NextPage in a loop,
		// ignoring the page token except for detecting the end of the
		// iteration.
		it := create().(iterator.Pageable)
		pager := iterator.NewPager(it, pageSize, "")
		msg, ok := testPager(fmt.Sprintf("ignore page token, pageSize %d", pageSize),
			vWant.Type(), wantPages,
			func(_ string, pagep interface{}) (string, error) {
				return pager.NextPage(pagep)
			})
		if !ok {
			return msg, false
		}
		// Second, by creating a new Pager for each page, passing in the page
		// token from the previous page, as would be done in a web handler.
		it = create().(iterator.Pageable)
		msg, ok = testPager(fmt.Sprintf("use page token, pageSize %d", pageSize),
			vWant.Type(), wantPages,
			func(pageToken string, pagep interface{}) (string, error) {
				return iterator.NewPager(it, pageSize, pageToken).NextPage(pagep)
			})
		if !ok {
			return msg, false
		}
	}
	return "", true
}

// Create the pages we expect to see.
func wantedPages(vWant reflect.Value, pageSize int) []interface{} {
	var pages []interface{}
	for i, j := 0, pageSize; i < vWant.Len(); i, j = j, j+pageSize {
		if j > vWant.Len() {
			j = vWant.Len()
		}
		pages = append(pages, vWant.Slice(i, j).Interface())
	}
	return pages
}

func testPager(prefix string, sliceType reflect.Type, wantPages []interface{},
	nextPage func(pageToken string, pagep interface{}) (string, error)) (string, bool) {
	tok := ""
	var err error
	for i := 0; i < len(wantPages)+1; i++ {
		vpagep := reflect.New(sliceType)
		tok, err = nextPage(tok, vpagep.Interface())
		if err != nil {
			return fmt.Sprintf("%s, page #%d: got error %v", prefix, i, err), false
		}
		if i == len(wantPages) {
			// Allow one empty page at the end.
			if vpagep.Elem().Len() != 0 || tok != "" {
				return fmt.Sprintf("%s: did not get one empty page at end", prefix), false
			}
			break
		}
		if msg, ok := compareSlices(vpagep.Elem(), reflect.ValueOf(wantPages[i])); !ok {
			return fmt.Sprintf("%s, page #%d:\n%s", prefix, i, msg), false
		}
		if tok == "" {
			if i != len(wantPages)-1 {
				return fmt.Sprintf("%s, page #%d: got empty page token", prefix, i), false
			}
			break
		}
	}
	return "", true
}

// Compare two slices element-by-element. If they are equal, return ("", true).
// Otherwise, return a description of the difference and false.
func compareSlices(vgot, vwant reflect.Value) (string, bool) {
	if got, want := vgot.Len(), vwant.Len(); got != want {
		return fmt.Sprintf("got %d items, want %d", got, want), false
	}
	for i := 0; i < vgot.Len(); i++ {
		if got, want := vgot.Index(i).Interface(), vwant.Index(i).Interface(); !reflect.DeepEqual(got, want) {
			return fmt.Sprintf("got[%d] = %+v\nwant   = %+v", i, got, want), false
		}
	}
	return "", true
}
