// Copyright 2016 Google Inc. All Rights Reserved.
//
// 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 pubsub

import (
	"errors"
	"reflect"
	"testing"

	"golang.org/x/net/context"
)

type fetchResult struct {
	msgs []*Message
	err  error
}

type fetcherService struct {
	service
	results        []fetchResult
	unexpectedCall bool
}

func (s *fetcherService) fetchMessages(ctx context.Context, subName string, maxMessages int32) ([]*Message, error) {
	if len(s.results) == 0 {
		s.unexpectedCall = true
		return nil, errors.New("bang")
	}
	ret := s.results[0]
	s.results = s.results[1:]
	return ret.msgs, ret.err
}

func TestPuller(t *testing.T) {
	s := &fetcherService{
		results: []fetchResult{
			{
				msgs: []*Message{{ackID: "a"}, {ackID: "b"}},
			},
			{},
			{
				msgs: []*Message{{ackID: "c"}, {ackID: "d"}},
			},
			{
				msgs: []*Message{{ackID: "e"}},
			},
		},
	}

	pulled := make(chan string, 10)

	pull := newPuller(s, "subname", context.Background(), 2, func(ackID string) { pulled <- ackID }, func(string) {})

	got := []string{}
	for i := 0; i < 5; i++ {
		m, err := pull.Next()
		got = append(got, m.ackID)
		if err != nil {
			t.Errorf("unexpected err from pull.Next: %v", err)
		}
	}
	_, err := pull.Next()
	if err == nil {
		t.Errorf("unexpected err from pull.Next: %v", err)
	}

	want := []string{"a", "b", "c", "d", "e"}
	if !reflect.DeepEqual(got, want) {
		t.Errorf("pulled ack ids: got: %v ; want: %v", got, want)
	}
}

func TestPullerAddsToKeepAlive(t *testing.T) {
	s := &fetcherService{
		results: []fetchResult{
			{
				msgs: []*Message{{ackID: "a"}, {ackID: "b"}},
			},
			{
				msgs: []*Message{{ackID: "c"}, {ackID: "d"}},
			},
		},
	}

	pulled := make(chan string, 10)

	pull := newPuller(s, "subname", context.Background(), 2, func(ackID string) { pulled <- ackID }, func(string) {})

	got := []string{}
	for i := 0; i < 3; i++ {
		m, err := pull.Next()
		got = append(got, m.ackID)
		if err != nil {
			t.Errorf("unexpected err from pull.Next: %v", err)
		}
	}

	want := []string{"a", "b", "c"}
	if !reflect.DeepEqual(got, want) {
		t.Errorf("pulled ack ids: got: %v ; want: %v", got, want)
	}

	close(pulled)
	// We should have seen "d" written to the channel too, even though it hasn't been returned yet.
	pulledIDs := []string{}
	for id := range pulled {
		pulledIDs = append(pulledIDs, id)
	}

	want = append(want, "d")
	if !reflect.DeepEqual(pulledIDs, want) {
		t.Errorf("pulled ack ids: got: %v ; want: %v", pulledIDs, want)
	}
}

func TestPullerRetriesOnce(t *testing.T) {
	bang := errors.New("bang")
	s := &fetcherService{
		results: []fetchResult{
			{
				err: bang,
			},
			{
				err: bang,
			},
		},
	}

	pull := newPuller(s, "subname", context.Background(), 2, func(string) {}, func(string) {})

	_, err := pull.Next()
	if err != bang {
		t.Errorf("pull.Next err got: %v, want: %v", err, bang)
	}

	if s.unexpectedCall {
		t.Errorf("unexpected retry")
	}
	if len(s.results) != 0 {
		t.Errorf("outstanding calls: got: %v, want: 0", len(s.results))
	}
}
