// Copyright 2016 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package iterator_test

import (
	"context"
	"encoding/json"
	"math"
	"reflect"
	"testing"

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

// Service represents the implementation of a Google API's List method.
// We want to test against a large range of possible valid behaviors.
// All the behaviors this can generate are valid under the spec for
// Google API paging.
type service struct {
	// End of the sequence. end-1 is the last value returned.
	end int
	// Maximum number of items to return in one RPC. Also the default page size.
	// If zero, max is unlimited.
	max int
	// If true, return two empty pages before each RPC that returns items, and
	// two zero pages at the end. E.g. if end = 5, max = 2 and the pageSize
	// parameter to List is zero, then the number of items returned in
	// successive RPCS is:
	//    0 0 2 0 0 2 0 0 1 0 0
	// Note that this implies that the RPC returning the last items will have a
	// non-empty page token.
	zeroes bool
}

// List simulates an API List RPC. It returns integers in the range [0, s.end).
func (s *service) List(pageSize int, pageToken string) ([]int, string, error) {
	max := s.max
	if max == 0 {
		max = math.MaxInt64
	}
	// Never give back any more than s.max.
	if pageSize <= 0 || pageSize > max {
		pageSize = max
	}
	state := &listState{}
	if pageToken != "" {
		if err := json.Unmarshal([]byte(pageToken), state); err != nil {
			return nil, "", err
		}
	}
	ints := state.advance(pageSize, s.end, s.zeroes)
	if state.Start == s.end && (!s.zeroes || state.NumZeroes == 2) {
		pageToken = ""
	} else {
		bytes, err := json.Marshal(state)
		if err != nil {
			return nil, "", err
		}
		pageToken = string(bytes)
	}
	return ints, pageToken, nil
}

type listState struct {
	Start     int // where to start this page
	NumZeroes int // number of consecutive empty pages before this
}

func (s *listState) advance(pageSize, end int, zeroes bool) []int {
	var page []int
	if zeroes && s.NumZeroes != 2 {
		// Return a zero page.
	} else {
		for i := s.Start; i < end && len(page) < pageSize; i++ {
			page = append(page, i)
		}
	}
	s.Start += len(page)
	if len(page) == 0 {
		s.NumZeroes++
	} else {
		s.NumZeroes = 0
	}
	return page
}

func TestServiceList(t *testing.T) {
	for _, test := range []struct {
		svc      service
		pageSize int
		want     [][]int
	}{
		{service{end: 0}, 0, [][]int{nil}},
		{service{end: 5}, 0, [][]int{{0, 1, 2, 3, 4}}},
		{service{end: 5}, 8, [][]int{{0, 1, 2, 3, 4}}},
		{service{end: 5}, 2, [][]int{{0, 1}, {2, 3}, {4}}},
		{service{end: 5, max: 2}, 0, [][]int{{0, 1}, {2, 3}, {4}}},
		{service{end: 5, max: 2}, 1, [][]int{{0}, {1}, {2}, {3}, {4}}},
		{service{end: 5, max: 2}, 10, [][]int{{0, 1}, {2, 3}, {4}}},
		{service{end: 5, zeroes: true}, 0, [][]int{nil, nil, {0, 1, 2, 3, 4}, nil, nil}},
		{service{end: 5, max: 3, zeroes: true}, 0, [][]int{nil, nil, {0, 1, 2}, nil, nil, {3, 4}, nil, nil}},
	} {
		var got [][]int
		token := ""
		for {
			items, nextToken, err := test.svc.List(test.pageSize, token)
			if err != nil {
				t.Fatalf("%v, %d: %v", test.svc, test.pageSize, err)
			}
			got = append(got, items)
			if nextToken == "" {
				break
			}
			token = nextToken
		}
		if !reflect.DeepEqual(got, test.want) {
			t.Errorf("%v, %d: got %v, want %v", test.svc, test.pageSize, got, test.want)
		}
	}
}

type Client struct{ s *service }

// ItemIterator is a sample implementation of a standard iterator.
type ItemIterator struct {
	pageInfo *iterator.PageInfo
	nextFunc func() error
	s        *service
	items    []int
}

// PageInfo returns a PageInfo, which supports pagination.
func (it *ItemIterator) PageInfo() *iterator.PageInfo { return it.pageInfo }

// Items is a sample implementation of an iterator-creating method.
func (c *Client) Items(ctx context.Context) *ItemIterator {
	it := &ItemIterator{s: c.s}
	it.pageInfo, it.nextFunc = iterator.NewPageInfo(
		it.fetch,
		func() int { return len(it.items) },
		func() interface{} { b := it.items; it.items = nil; return b })
	return it
}

func (it *ItemIterator) fetch(pageSize int, pageToken string) (string, error) {
	items, tok, err := it.s.List(pageSize, pageToken)
	it.items = append(it.items, items...)
	return tok, err
}

func (it *ItemIterator) Next() (int, error) {
	if err := it.nextFunc(); err != nil {
		return 0, err
	}
	item := it.items[0]
	it.items = it.items[1:]
	return item, nil
}

func TestNext(t *testing.T) {
	// Test the iterator's Next method with a variety of different service behaviors.
	// This is primarily a test of PageInfo.next.
	for _, svc := range []service{
		{end: 0},
		{end: 5},
		{end: 5, max: 1},
		{end: 5, max: 2},
		{end: 5, zeroes: true},
		{end: 5, max: 2, zeroes: true},
	} {
		client := &Client{&svc}

		msg, ok := itest.TestIterator(
			seq(0, svc.end),
			func() interface{} { return client.Items(ctx) },
			func(it interface{}) (interface{}, error) { return it.(*ItemIterator).Next() })
		if !ok {
			t.Errorf("%+v: %s", svc, msg)
		}
	}
}

// TODO(jba): test setting PageInfo.MaxSize
// TODO(jba): test setting PageInfo.Token

// Verify that, for an iterator that uses PageInfo.next to implement its Next
// method, using Next and NextPage together result in an error.
func TestNextWithNextPage(t *testing.T) {
	client := &Client{&service{end: 11}}
	var items []int

	// Calling Next before NextPage.
	it := client.Items(ctx)
	it.Next()
	_, err := iterator.NewPager(it, 1, "").NextPage(&items)
	if err == nil {
		t.Error("NextPage after Next: got nil, want error")
	}
	_, err = it.Next()
	if err == nil {
		t.Error("Next after NextPage: got nil, want error")
	}

	// Next between two calls to NextPage.
	it = client.Items(ctx)
	p := iterator.NewPager(it, 1, "")
	p.NextPage(&items)
	_, err = it.Next()
	if err == nil {
		t.Error("Next after NextPage: got nil, want error")
	}
	_, err = p.NextPage(&items)
	if err == nil {
		t.Error("second NextPage after Next: got nil, want error")
	}
}

// Verify that we turn various potential reflection panics into errors.
func TestNextPageReflectionErrors(t *testing.T) {
	client := &Client{&service{end: 1}}
	p := iterator.NewPager(client.Items(ctx), 1, "")

	// Passing the nil interface value.
	_, err := p.NextPage(nil)
	if err == nil {
		t.Error("nil: got nil, want error")
	}

	// Passing a non-slice.
	_, err = p.NextPage(17)
	if err == nil {
		t.Error("non-slice: got nil, want error")
	}

	// Passing a slice of the wrong type.
	var bools []bool
	_, err = p.NextPage(&bools)
	if err == nil {
		t.Error("wrong type: got nil, want error")
	}

	// Using a slice of the right type, but not passing a pointer to it.
	var ints []int
	_, err = p.NextPage(ints)
	if err == nil {
		t.Error("not a pointer: got nil, want error")
	}
}

// seq returns a slice containing the values in [from, to).
func seq(from, to int) []int {
	var r []int
	for i := from; i < to; i++ {
		r = append(r, i)
	}
	return r
}
