/*
Copyright 2017 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 spanner

import (
	"errors"
	"sync"
	"testing"
	"time"

	"cloud.google.com/go/spanner/internal/testutil"
	"golang.org/x/net/context"
	sppb "google.golang.org/genproto/googleapis/spanner/v1"
	"google.golang.org/grpc/codes"
)

var (
	errAbrt = spannerErrorf(codes.Aborted, "")
	errUsr  = errors.New("error")
)

// setup sets up a Client using mockclient
func mockClient(t *testing.T) (*sessionPool, *testutil.MockCloudSpannerClient, *Client) {
	var (
		mc       = testutil.NewMockCloudSpannerClient(t)
		spc      = SessionPoolConfig{}
		database = "mockdb"
	)
	spc.getRPCClient = func() (sppb.SpannerClient, error) {
		return mc, nil
	}
	sp, err := newSessionPool(database, spc, nil)
	if err != nil {
		t.Fatalf("cannot create session pool: %v", err)
	}
	return sp, mc, &Client{
		database:     database,
		idleSessions: sp,
	}
}

// TestReadOnlyAcquire tests acquire for ReadOnlyTransaction.
func TestReadOnlyAcquire(t *testing.T) {
	t.Parallel()
	_, mc, client := mockClient(t)
	defer client.Close()
	mc.SetActions(
		testutil.Action{"BeginTransaction", errUsr},
		testutil.Action{"BeginTransaction", nil},
		testutil.Action{"BeginTransaction", nil},
	)

	// Singleuse should only be used once.
	txn := client.Single()
	defer txn.Close()
	_, _, e := txn.acquire(context.Background())
	if e != nil {
		t.Errorf("Acquire for single use, got %v, want nil.", e)
	}
	_, _, e = txn.acquire(context.Background())
	if wantErr := errTxClosed(); !testEqual(e, wantErr) {
		t.Errorf("Second acquire for single use, got %v, want %v.", e, wantErr)
	}
	// Multiuse can recover from acquire failure.
	txn = client.ReadOnlyTransaction()
	_, _, e = txn.acquire(context.Background())
	if wantErr := toSpannerError(errUsr); !testEqual(e, wantErr) {
		t.Errorf("Acquire for multi use, got %v, want %v.", e, wantErr)
	}
	_, _, e = txn.acquire(context.Background())
	if e != nil {
		t.Errorf("Acquire for multi use, got %v, want nil.", e)
	}
	txn.Close()
	// Multiuse can not be used after close.
	_, _, e = txn.acquire(context.Background())
	if wantErr := errTxClosed(); !testEqual(e, wantErr) {
		t.Errorf("Second acquire for multi use, got %v, want %v.", e, wantErr)
	}
	// Multiuse can be acquired concurrently.
	txn = client.ReadOnlyTransaction()
	defer txn.Close()
	mc.Freeze()
	var (
		sh1 *sessionHandle
		sh2 *sessionHandle
		ts1 *sppb.TransactionSelector
		ts2 *sppb.TransactionSelector
		wg  = sync.WaitGroup{}
	)
	acquire := func(sh **sessionHandle, ts **sppb.TransactionSelector) {
		defer wg.Done()
		var e error
		*sh, *ts, e = txn.acquire(context.Background())
		if e != nil {
			t.Errorf("Concurrent acquire for multiuse, got %v, expect nil.", e)
		}
	}
	wg.Add(2)
	go acquire(&sh1, &ts1)
	go acquire(&sh2, &ts2)
	<-time.After(100 * time.Millisecond)
	mc.Unfreeze()
	wg.Wait()
	if !testEqual(sh1.session, sh2.session) {
		t.Errorf("Expect acquire to get same session handle, got %v and %v.", sh1, sh2)
	}
	if !testEqual(ts1, ts2) {
		t.Errorf("Expect acquire to get same transaction selector, got %v and %v.", ts1, ts2)
	}
}

// TestRetryOnAbort tests transaction retries on abort.
func TestRetryOnAbort(t *testing.T) {
	t.Parallel()
	_, mc, client := mockClient(t)
	defer client.Close()
	// commit in writeOnlyTransaction
	mc.SetActions(
		testutil.Action{"Commit", errAbrt}, // abort on first commit
		testutil.Action{"Commit", nil},
	)

	ms := []*Mutation{
		Insert("Accounts", []string{"AccountId", "Nickname", "Balance"}, []interface{}{int64(1), "Foo", int64(50)}),
		Insert("Accounts", []string{"AccountId", "Nickname", "Balance"}, []interface{}{int64(2), "Bar", int64(1)}),
	}
	if _, e := client.Apply(context.Background(), ms, ApplyAtLeastOnce()); e != nil {
		t.Errorf("applyAtLeastOnce retry on abort, got %v, want nil.", e)
	}
	// begin and commit in ReadWriteTransaction
	mc.SetActions(
		testutil.Action{"BeginTransaction", nil},     // let takeWriteSession succeed and get a session handle
		testutil.Action{"Commit", errAbrt},           // let first commit fail and retry will begin new transaction
		testutil.Action{"BeginTransaction", errAbrt}, // this time we can fail the begin attempt
		testutil.Action{"BeginTransaction", nil},
		testutil.Action{"Commit", nil},
	)

	if _, e := client.Apply(context.Background(), ms); e != nil {
		t.Errorf("ReadWriteTransaction retry on abort, got %v, want nil.", e)
	}
}

// TestBadSession tests bad session (session not found error).
// TODO: session closed from transaction close
func TestBadSession(t *testing.T) {
	t.Parallel()
	ctx := context.Background()
	sp, mc, client := mockClient(t)
	defer client.Close()
	var sid string
	// Prepare a session, get the session id for use in testing.
	if s, e := sp.take(ctx); e != nil {
		t.Fatal("Prepare session failed.")
	} else {
		sid = s.getID()
		s.recycle()
	}

	wantErr := spannerErrorf(codes.NotFound, "Session not found: %v", sid)
	// ReadOnlyTransaction
	mc.SetActions(
		testutil.Action{"BeginTransaction", wantErr},
		testutil.Action{"BeginTransaction", wantErr},
		testutil.Action{"BeginTransaction", wantErr},
	)
	txn := client.ReadOnlyTransaction()
	defer txn.Close()
	if _, _, got := txn.acquire(ctx); !testEqual(wantErr, got) {
		t.Errorf("Expect acquire to fail, got %v, want %v.", got, wantErr)
	}
	// The failure should recycle the session, we expect it to be used in following requests.
	if got := txn.Query(ctx, NewStatement("SELECT 1")); !testEqual(wantErr, got.err) {
		t.Errorf("Expect Query to fail, got %v, want %v.", got.err, wantErr)
	}
	if got := txn.Read(ctx, "Users", KeySets(Key{"alice"}, Key{"bob"}), []string{"name", "email"}); !testEqual(wantErr, got.err) {
		t.Errorf("Expect Read to fail, got %v, want %v.", got.err, wantErr)
	}
	// writeOnlyTransaction
	ms := []*Mutation{
		Insert("Accounts", []string{"AccountId", "Nickname", "Balance"}, []interface{}{int64(1), "Foo", int64(50)}),
		Insert("Accounts", []string{"AccountId", "Nickname", "Balance"}, []interface{}{int64(2), "Bar", int64(1)}),
	}
	mc.SetActions(testutil.Action{"Commit", wantErr})
	if _, got := client.Apply(context.Background(), ms, ApplyAtLeastOnce()); !testEqual(wantErr, got) {
		t.Errorf("Expect applyAtLeastOnce to fail, got %v, want %v.", got, wantErr)
	}
}

func TestFunctionErrorReturned(t *testing.T) {
	t.Parallel()
	_, mc, client := mockClient(t)
	defer client.Close()
	mc.SetActions(
		testutil.Action{"BeginTransaction", nil},
		testutil.Action{"Rollback", nil},
	)

	want := errors.New("an error")
	_, got := client.ReadWriteTransaction(context.Background(),
		func(context.Context, *ReadWriteTransaction) error { return want })
	if got != want {
		t.Errorf("got <%v>, want <%v>", got, want)
	}
	mc.CheckActionsConsumed()
}
