// 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 internal

import (
	"bytes"
	"context"
	"errors"
	"fmt"
	"io"
	"log"
	"sync"
	"testing"

	"google.golang.org/grpc"

	pb "google.golang.org/genproto/googleapis/bytestream"
)

const (
	testName = "testName"
	testData = "0123456789"
)

var (
	setupServerOnce sync.Once
	server          *Server
)

func TestNewServerWithInvalidInputs(t *testing.T) {
	_, err := NewServer(grpc.NewServer(), nil, nil)
	if err == nil {
		t.Fatal("NewServer(nil, nil) should not succeed")
	}
}

func TestServerWrite(t *testing.T) {
	testCases := []struct {
		name              string
		writeHandler      WriteHandler
		input             []interface{}
		writeCount        int
		allowEmptyCommits bool
		allowOverwrite    bool
		wantErr           bool
		wantResponse      int
	}{
		{
			name:         "empty resource name",
			writeHandler: &TestWriteHandler{},
			input: []interface{}{
				&pb.WriteRequest{
					FinishWrite: true,
					Data:        []byte(testData),
				},
			},
			writeCount:   1,
			wantErr:      true,
			wantResponse: 0,
		}, {
			name:         "Recv returns io.EOF",
			writeHandler: &TestWriteHandler{},
			input: []interface{}{
				io.EOF,
			},
			writeCount:   1,
			wantErr:      false,
			wantResponse: 0,
		}, {
			name:         "Recv returns error, 0 WriteRequests",
			writeHandler: &TestWriteHandler{},
			input: []interface{}{
				errors.New("Recv returns error, 0 WriteRequests"),
			},
			writeCount:   1,
			wantErr:      true,
			wantResponse: 0,
		}, {
			name:         "simple test",
			writeHandler: &TestWriteHandler{},
			input: []interface{}{
				&pb.WriteRequest{
					ResourceName: testName,
					WriteOffset:  0,
					FinishWrite:  true,
					Data:         []byte(testData),
				},
				io.EOF,
			},
			writeCount:   1,
			wantResponse: 1,
		}, {
			name:         "Recv returns error, 1 WriteRequests",
			writeHandler: &TestWriteHandler{},
			input: []interface{}{
				&pb.WriteRequest{
					ResourceName: testName,
					WriteOffset:  0,
					FinishWrite:  false,
					Data:         []byte(testData),
				},
				errors.New("Recv returns error, 1 WriteRequests"),
			},
			writeCount:   1,
			wantErr:      true,
			wantResponse: 0,
		}, {
			name:         "attempt to overwrite the same name",
			writeHandler: &TestWriteHandler{},
			input: []interface{}{
				&pb.WriteRequest{
					ResourceName: testName,
					WriteOffset:  0,
					FinishWrite:  true,
					Data:         []byte(testData),
				},
				io.EOF,
				&pb.WriteRequest{
					ResourceName: testName,
					WriteOffset:  0,
					FinishWrite:  true,
					Data:         []byte(testData),
				},
			},
			writeCount:   2,
			wantErr:      true,
			wantResponse: 1,
		}, {
			name:         "overwrite with the same name + AllowOverwrite",
			writeHandler: &TestWriteHandler{},
			input: []interface{}{
				&pb.WriteRequest{
					ResourceName: testName,
					WriteOffset:  0,
					FinishWrite:  true,
					Data:         []byte(testData),
				},
				io.EOF,
				&pb.WriteRequest{
					ResourceName: testName,
					WriteOffset:  0,
					FinishWrite:  true,
					Data:         []byte(testData),
				},
				io.EOF,
			},
			writeCount:     2,
			allowOverwrite: true,
			wantResponse:   2,
		}, {
			name:         "two WriteRequests - 1st is empty",
			writeHandler: &TestWriteHandler{},
			input: []interface{}{
				&pb.WriteRequest{
					ResourceName: testName,
					WriteOffset:  0,
					FinishWrite:  false,
					Data:         nil,
				},
				&pb.WriteRequest{
					ResourceName: testName,
					WriteOffset:  0,
					FinishWrite:  true,
					Data:         []byte(testData),
				},
				io.EOF,
			},
			writeCount:        1,
			wantResponse:      1,
			allowEmptyCommits: true,
		}, {
			name:         "two WriteRequests - 2nd is empty",
			writeHandler: &TestWriteHandler{},
			input: []interface{}{
				&pb.WriteRequest{
					ResourceName: testName,
					WriteOffset:  0,
					FinishWrite:  false,
					Data:         []byte(testData),
				},
				&pb.WriteRequest{
					ResourceName: testName,
					WriteOffset:  int64(len(testData)),
					FinishWrite:  true,
					Data:         nil,
				},
				io.EOF,
			},
			writeCount:   1,
			wantResponse: 1,
		}, {
			name:         "two WriteRequests - all empty",
			writeHandler: &TestWriteHandler{},
			input: []interface{}{
				&pb.WriteRequest{
					ResourceName: testName,
					WriteOffset:  0,
					FinishWrite:  false,
					Data:         nil,
				},
				&pb.WriteRequest{
					ResourceName: testName,
					WriteOffset:  0,
					FinishWrite:  true,
					Data:         nil,
				},
			},
			writeCount:        1,
			wantErr:           true,
			wantResponse:      1,
			allowEmptyCommits: true,
		}, {
			name:         "two WriteRequests - varying offset",
			writeHandler: &TestWriteHandler{},
			input: []interface{}{
				&pb.WriteRequest{
					ResourceName: testName,
					WriteOffset:  100,
					FinishWrite:  false,
					Data:         []byte(testData),
				},
				&pb.WriteRequest{
					ResourceName: testName,
					WriteOffset:  100 + int64(len(testData)),
					FinishWrite:  true,
					Data:         []byte(testData),
				},
				io.EOF,
			},
			writeCount:   1,
			wantResponse: 1,
		}, {
			name:         "two WriteRequests - disjoint offset",
			writeHandler: &TestWriteHandler{},
			input: []interface{}{
				&pb.WriteRequest{
					ResourceName: testName,
					WriteOffset:  100,
					FinishWrite:  false,
					Data:         []byte(testData),
				},
				&pb.WriteRequest{
					ResourceName: testName,
					WriteOffset:  200,
					FinishWrite:  true,
					Data:         []byte(testData),
				},
			},
			writeCount:   1,
			wantErr:      true,
			wantResponse: 0,
		}, {
			name:         "fails with UngettableWriteHandler",
			writeHandler: &UngettableWriteHandler{},
			input: []interface{}{
				&pb.WriteRequest{
					ResourceName: testName,
					WriteOffset:  0,
					FinishWrite:  true,
					Data:         []byte(testData),
				},
			},
			writeCount: 1,
			wantErr:    true,
		}, {
			name:         "fails with UnwritableWriteHandler",
			writeHandler: &UnwritableWriteHandler{},
			input: []interface{}{
				&pb.WriteRequest{
					ResourceName: testName,
					WriteOffset:  0,
					FinishWrite:  true,
					Data:         []byte(testData),
				},
			},
			writeCount: 1,
			wantErr:    true,
		}, {
			name:         "fails with UnclosableWriteHandler",
			writeHandler: &UnclosableWriteHandler{},
			input: []interface{}{
				&pb.WriteRequest{
					ResourceName: testName,
					WriteOffset:  0,
					FinishWrite:  true,
					Data:         []byte(testData),
				},
			},
			writeCount:   1,
			wantErr:      true,
			wantResponse: 1,
		}, {
			name:         "fails with nil WriteHandler",
			writeHandler: nil,
			input: []interface{}{
				&pb.WriteRequest{
					ResourceName: testName,
					WriteOffset:  0,
					FinishWrite:  true,
					Data:         []byte(testData),
				},
			},
			writeCount: 1,
			wantErr:    true,
		},
	}

	ctx := context.Background()
	for _, tc := range testCases {
		readHandler := &TestReadHandler{}
		if tc.writeHandler != nil {
			readHandler = nil
		}
		setupServer(readHandler, tc.writeHandler)
		server.AllowOverwrite = tc.allowOverwrite
		var requestCount, responseCount int
		var err error

		for i := 0; i < tc.writeCount; i++ {
			err = server.rpc.Write(&fakeWriteServerImpl{
				ctx: ctx,
				receiver: func() (*pb.WriteRequest, error) {
					if requestCount >= len(tc.input) {
						t.Fatalf("%s: got %d call(s) to Recv, want %d from len(input)", tc.name, requestCount+1, len(tc.input))
					}
					v := tc.input[requestCount]
					requestCount++
					request, ok := v.(*pb.WriteRequest)
					if ok {
						return request, nil
					}
					err, ok := v.(error)
					if !ok {
						t.Fatalf("%s: unknown input: %v", tc.name, v)
					}
					return nil, err
				},
				sender: func(response *pb.WriteResponse) error {
					if !tc.allowEmptyCommits && response.CommittedSize == 0 {
						t.Fatalf("%s: invalid response: WriteResponse %v", tc.name, response)
					}
					responseCount++
					return nil
				},
			})
			gotErr := (err != nil)
			if i+1 < tc.writeCount {
				if gotErr {
					t.Errorf("%s: Write got err=%v, wantErr=%t, but on Write[%d/%d]. Error should not happen until last call to Write.", tc.name, err, tc.wantErr, i+1, tc.writeCount)
					break // The t.Errorf conditions below may erroneously fire, pay them no mind.
				}
			} else if gotErr != tc.wantErr {
				t.Errorf("%s: Write got err=%v, wantErr=%t", tc.name, err, tc.wantErr)
				break // The t.Errorf conditions below may erroneously fire, pay them no mind.
			}
		}
		if requestCount != len(tc.input) {
			t.Errorf("%s: got %d call(s) to Recv, want %d", tc.name, requestCount, len(tc.input))
		}
		if responseCount != tc.wantResponse {
			t.Errorf("%s: got %d call(s) to SendProto, want %d", tc.name, responseCount, tc.wantResponse)
		}
	}
}

func TestServerWrite_SendAndCloseError(t *testing.T) {
	const (
		wantRequest  = 2
		wantResponse = 1
	)

	ctx := context.Background()
	setupServer(nil, &TestWriteHandler{})
	var requestCount, responseCount int

	err := server.rpc.Write(&fakeWriteServerImpl{
		ctx: ctx,
		receiver: func() (*pb.WriteRequest, error) {
			if requestCount >= wantRequest {
				t.Fatalf("got %d call(s) to Recv, want %d", requestCount+1, wantRequest)
			}
			requestCount++
			return &pb.WriteRequest{
				ResourceName: testName,
				WriteOffset:  0,
				FinishWrite:  true,
				Data:         []byte(testData),
			}, nil
		},
		sender: func(response *pb.WriteResponse) error {
			responseCount++
			return errors.New("TestServerWrite SendProto error")
		},
	})
	if err == nil {
		t.Errorf("Write should have failed, but succeeded")
	}
	if requestCount != wantRequest {
		t.Errorf("got %d call(s) to Recv, want %d", requestCount, wantRequest)
	}
	if responseCount != wantResponse {
		t.Errorf("got %d call(s) to SendProto, want %d", responseCount, wantResponse)
	}
}

func TestQueryWriteStatus(t *testing.T) {
	testCases := []struct {
		name         string
		existingName string
		requestName  string
		wantErr      bool
	}{
		{
			name:         "existing name should work",
			existingName: testName,
			requestName:  testName,
		}, {
			name:         "missing name should break",
			existingName: testName,
			requestName:  "invalidName",
			wantErr:      true,
		},
	}

	ctx := context.Background()
	for _, tc := range testCases {
		setupServer(nil, &TestWriteHandler{})
		server.status[tc.existingName] = &pb.QueryWriteStatusResponse{}

		_, err := server.rpc.QueryWriteStatus(ctx, &pb.QueryWriteStatusRequest{
			ResourceName: tc.requestName,
		})

		if gotErr := (err != nil); gotErr != tc.wantErr {
			t.Errorf("%s: QueryWriteStatus(%q) got err=%v, wantErr=%t", tc.name, tc.requestName, err, tc.wantErr)
		}
	}
}

func TestServerRead(t *testing.T) {
	testCases := []struct {
		name         string
		readHandler  ReadHandler
		input        *pb.ReadRequest
		readCount    int
		wantErr      bool
		wantResponse []string
	}{
		{
			name:        "empty resource name",
			readHandler: &TestReadHandler{},
			input: &pb.ReadRequest{
				ReadLimit: 1,
			},
			readCount:    1,
			wantErr:      true,
			wantResponse: []string{},
		}, {
			name:        "test ReadLimit=-1",
			readHandler: &TestReadHandler{buf: testData},
			input: &pb.ReadRequest{
				ResourceName: testName,
				ReadOffset:   0,
				ReadLimit:    -1,
			},
			readCount: 1,
			wantErr:   true,
		}, {
			name:        "test ReadLimit=1",
			readHandler: &TestReadHandler{buf: testData},
			input: &pb.ReadRequest{
				ResourceName: testName,
				ReadOffset:   0,
				ReadLimit:    1,
			},
			readCount:    1,
			wantResponse: []string{"0"},
		}, {
			name:        "test ReadLimit=2",
			readHandler: &TestReadHandler{buf: testData},
			input: &pb.ReadRequest{
				ResourceName: testName,
				ReadOffset:   0,
				ReadLimit:    2,
			},
			readCount:    1,
			wantResponse: []string{"01"},
		}, {
			name:        "test ReadOffset=1 ReadLimit=2",
			readHandler: &TestReadHandler{buf: testData},
			input: &pb.ReadRequest{
				ResourceName: testName,
				ReadOffset:   1,
				ReadLimit:    2,
			},
			readCount:    1,
			wantResponse: []string{"12"},
		}, {
			name:        "test ReadOffset=2 ReadLimit=2",
			readHandler: &TestReadHandler{buf: testData},
			input: &pb.ReadRequest{
				ResourceName: testName,
				ReadOffset:   2,
				ReadLimit:    2,
			},
			readCount:    1,
			wantResponse: []string{"23"},
		}, {
			name:        "read all testData at exactly the limit",
			readHandler: &TestReadHandler{buf: testData},
			input: &pb.ReadRequest{
				ResourceName: testName,
				ReadOffset:   0,
				ReadLimit:    int64(len(testData)),
			},
			readCount:    1,
			wantResponse: []string{"0123456789"},
		}, {
			name:        "read all testData",
			readHandler: &TestReadHandler{buf: testData},
			input: &pb.ReadRequest{
				ResourceName: testName,
				ReadOffset:   0,
				ReadLimit:    int64(len(testData)) * 2,
			},
			readCount:    1,
			wantResponse: []string{"0123456789"},
		}, {
			name:        "read all testData 2 times",
			readHandler: &TestReadHandler{buf: testData},
			input: &pb.ReadRequest{
				ResourceName: testName,
				ReadOffset:   0,
				ReadLimit:    int64(len(testData)) * 2,
			},
			readCount:    2,
			wantResponse: []string{"0123456789", "0123456789"},
		}, {
			name:        "test ReadLimit=0",
			readHandler: &TestReadHandler{buf: testData},
			input: &pb.ReadRequest{
				ResourceName: testName,
				ReadOffset:   0,
				ReadLimit:    0,
			},
			readCount:    1,
			wantResponse: []string{"0123456789"},
		}, {
			name:        "test ReadLimit=1000",
			readHandler: &TestReadHandler{buf: testData},
			input: &pb.ReadRequest{
				ResourceName: testName,
				ReadOffset:   0,
				ReadLimit:    1000,
			},
			readCount:    1,
			wantResponse: []string{"0123456789"},
		}, {
			name:        "fails with UngettableReadHandler",
			readHandler: &UngettableReadHandler{},
			input: &pb.ReadRequest{
				ResourceName: testName,
				ReadOffset:   0,
				ReadLimit:    int64(len(testData)),
			},
			readCount: 1,
			wantErr:   true,
		}, {
			name:        "fails with UnreadableReadHandler",
			readHandler: &UnreadableReadHandler{},
			input: &pb.ReadRequest{
				ResourceName: testName,
				ReadOffset:   0,
				ReadLimit:    int64(len(testData)),
			},
			readCount: 1,
			wantErr:   true,
		}, {
			name:        "fails with UnclosableReadHandler",
			readHandler: &UnclosableReadHandler{buf: testData},
			input: &pb.ReadRequest{
				ResourceName: testName,
				ReadOffset:   0,
				ReadLimit:    int64(len(testData)) * 2,
			},
			readCount:    1,
			wantErr:      true,
			wantResponse: []string{"0123456789"},
		}, {
			name:        "fails with nil ReadRequest",
			readHandler: &TestReadHandler{buf: testData},
			readCount:   1,
			wantErr:     true,
		}, {
			name:        "fails with nil ReadHandler",
			readHandler: nil,
			readCount:   1,
			wantErr:     true,
		},
	}

	ctx := context.Background()
	for _, tc := range testCases {
		var writeHandler WriteHandler
		if tc.readHandler == nil {
			writeHandler = &TestWriteHandler{}
		}
		setupServer(tc.readHandler, writeHandler)
		var responseCount int
		var err error

		for i := 0; i < tc.readCount; i++ {
			err = server.rpc.Read(tc.input, &fakeReadServerImpl{
				ctx: ctx,
				sender: func(response *pb.ReadResponse) error {
					if responseCount >= len(tc.wantResponse) {
						t.Fatalf("%s: got %d call(s) to Send(), want %d", tc.name, responseCount+1, len(tc.wantResponse))
					}
					if got, want := string(response.Data), tc.wantResponse[responseCount]; got != want {
						t.Fatalf("%s: response[%d] got %q, want %q", tc.name, responseCount, got, want)
					}
					responseCount++
					return nil
				},
			})
			gotErr := (err != nil)
			if i+1 < tc.readCount {
				if gotErr {
					t.Errorf("%s: Read got err=%v, wantErr=%t, but on Read[%d/%d]. Error should not happen until last call to Read", tc.name, err, tc.wantErr, i+1, tc.readCount)
					break
				}
			} else if gotErr != tc.wantErr {
				t.Errorf("%s: Read got err=%v, wantErr=%t", tc.name, err, tc.wantErr)
				break
			}
		}
		if responseCount != len(tc.wantResponse) {
			t.Errorf("%s: got %d call(s) to Send, want %d", tc.name, responseCount, len(tc.wantResponse))
		}
	}
}

func TestServerRead_SendError(t *testing.T) {
	setupServer(&TestReadHandler{buf: testData}, nil)

	err := server.rpc.Read(&pb.ReadRequest{
		ResourceName: testName,
		ReadOffset:   0,
		ReadLimit:    int64(len(testData)) * 2,
	}, &fakeReadServerImpl{
		ctx: context.Background(),
		sender: func(response *pb.ReadResponse) error {
			if string(response.Data) != testData {
				t.Fatalf("Send: got %v, want %q", response, testData)
			}
			return errors.New("TestServerRead Send() error")
		},
	})

	if err == nil {
		t.Fatal("Read() should have failed, but succeeded")
	}
}

type fakeWriteServerImpl struct {
	pb.ByteStream_WriteServer
	ctx      context.Context
	receiver func() (*pb.WriteRequest, error)
	sender   func(*pb.WriteResponse) error
}

func (fake *fakeWriteServerImpl) Context() context.Context {
	return fake.ctx
}

func (fake *fakeWriteServerImpl) Recv() (*pb.WriteRequest, error) {
	return fake.receiver()
}

func (fake *fakeWriteServerImpl) SendMsg(m interface{}) error {
	return fake.sender(m.(*pb.WriteResponse))
}

func (fake *fakeWriteServerImpl) SendAndClose(m *pb.WriteResponse) error {
	fake.sender(m)
	return nil
}

type fakeReadServerImpl struct {
	pb.ByteStream_ReadServer
	ctx    context.Context
	sender func(*pb.ReadResponse) error
}

func (fake *fakeReadServerImpl) Context() context.Context {
	return fake.ctx
}

func (fake *fakeReadServerImpl) Send(response *pb.ReadResponse) error {
	return fake.sender(response)
}

type TestWriteHandler struct {
	buf  bytes.Buffer // bytes.Buffer implements io.Writer
	name string       // This service can handle one name only.
}

func (w *TestWriteHandler) GetWriter(ctx context.Context, name string, initOffset int64) (io.Writer, error) {
	if w.name == "" {
		w.name = name
	} else if w.name != name {
		return nil, fmt.Errorf("writer already has name=%q, now a new name=%q confuses me", w.name, name)
	}
	// initOffset is ignored.
	return &w.buf, nil
}

func (w *TestWriteHandler) Close(ctx context.Context, name string) error {
	w.name = ""
	w.buf.Reset()
	return nil
}

type UngettableWriteHandler struct{}

func (w *UngettableWriteHandler) GetWriter(ctx context.Context, name string, initOffset int64) (io.Writer, error) {
	return nil, errors.New("UngettableWriteHandler.GetWriter() always fails")
}

func (w *UngettableWriteHandler) Close(ctx context.Context, name string) error {
	return nil
}

type UnwritableWriter struct{}

func (w *UnwritableWriter) Write(p []byte) (int, error) {
	return 0, errors.New("UnwritableWriter.Write() always fails")
}

type UnwritableWriteHandler struct{}

func (w *UnwritableWriteHandler) GetWriter(ctx context.Context, name string, initOffset int64) (io.Writer, error) {
	return &UnwritableWriter{}, nil
}

func (w *UnwritableWriteHandler) Close(ctx context.Context, name string) error {
	return nil
}

type UnclosableWriter struct{}

func (w *UnclosableWriter) Write(p []byte) (int, error) {
	return len(p), nil
}

type UnclosableWriteHandler struct{}

func (w *UnclosableWriteHandler) GetWriter(ctx context.Context, name string, initOffset int64) (io.Writer, error) {
	return &UnclosableWriter{}, nil
}

func (w *UnclosableWriteHandler) Close(ctx context.Context, name string) error {
	return errors.New("UnclosableWriteHandler.Close() always fails")
}

type TestReadHandler struct {
	buf  string
	name string // This service can handle one name only.
}

// GetWriter() returns an io.ReaderAt to accept reads from the given name.
func (r *TestReadHandler) GetReader(ctx context.Context, name string) (io.ReaderAt, error) {
	if r.name == "" {
		r.name = name
	} else if r.name != name {
		return nil, fmt.Errorf("reader already has name=%q, now a new name=%q confuses me", r.name, name)
	}
	return bytes.NewReader([]byte(r.buf)), nil
}

// Close does nothing.
func (r *TestReadHandler) Close(ctx context.Context, name string) error {
	return nil
}

type UngettableReadHandler struct{}

func (r *UngettableReadHandler) GetReader(ctx context.Context, name string) (io.ReaderAt, error) {
	return nil, errors.New("UngettableReadHandler.GetReader() always fails")
}

func (r *UngettableReadHandler) Close(ctx context.Context, name string) error {
	return nil
}

type UnreadableReader struct{}

func (r *UnreadableReader) ReadAt(p []byte, offset int64) (int, error) {
	return 0, errors.New("UnreadableReader.ReadAt() always fails")
}

type UnreadableReadHandler struct{}

func (r *UnreadableReadHandler) GetReader(ctx context.Context, name string) (io.ReaderAt, error) {
	return &UnreadableReader{}, nil
}

func (r *UnreadableReadHandler) Close(ctx context.Context, name string) error {
	return nil
}

type UnclosableReadHandler struct {
	buf string
}

func (r *UnclosableReadHandler) GetReader(ctx context.Context, name string) (io.ReaderAt, error) {
	return bytes.NewReader([]byte(r.buf)), nil
}

func (r *UnclosableReadHandler) Close(ctx context.Context, name string) error {
	return fmt.Errorf("UnclosableReader.Close(%s) always fails", name)
}

func registerServer() {
	gsrv := grpc.NewServer()
	var err error
	server, err = NewServer(gsrv, &TestReadHandler{}, &TestWriteHandler{})
	if err != nil {
		log.Fatalf("NewServer() failed: %v", err)
	}
}

func setupServer(readHandler ReadHandler, writeHandler WriteHandler) {
	setupServerOnce.Do(registerServer)
	server.status = make(map[string]*pb.QueryWriteStatusResponse)
	server.readHandler = readHandler
	server.writeHandler = writeHandler
}
