// Copyright 2020 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
//
//     https://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

package pscompat

import (
	"context"
	"errors"
	"testing"

	"cloud.google.com/go/pubsub"
	"cloud.google.com/go/pubsublite/internal/test"
	"cloud.google.com/go/pubsublite/internal/wire"

	pb "cloud.google.com/go/pubsublite/apiv1/pubsublitepb"
)

// mockWirePublisher is a mock implementation of the wire.Publisher interface.
// It uses test.RPCVerifier to install fake PublishResults for each Publish
// call.
type mockWirePublisher struct {
	Verifier *test.RPCVerifier
	Stopped  bool
	err      error
}

func (mp *mockWirePublisher) Publish(msg *pb.PubSubMessage, onResult wire.PublishResultFunc) {
	resp, err := mp.Verifier.Pop(msg)
	if err != nil {
		mp.err = err
		onResult(nil, err)
		return
	}
	result := resp.(*wire.MessageMetadata)
	onResult(result, nil)
}

func (mp *mockWirePublisher) Start()             {}
func (mp *mockWirePublisher) Stop()              { mp.Stopped = true }
func (mp *mockWirePublisher) WaitStarted() error { return mp.err }
func (mp *mockWirePublisher) WaitStopped() error { return mp.err }
func (mp *mockWirePublisher) Error() error       { return mp.err }

func newTestPublisherClient(verifier *test.RPCVerifier, settings PublishSettings) *PublisherClient {
	return &PublisherClient{
		settings: settings,
		wirePub:  &mockWirePublisher{Verifier: verifier},
	}
}

func TestPublisherClientTransformMessage(t *testing.T) {
	ctx := context.Background()
	input := &pubsub.Message{
		Data:        []byte("data"),
		OrderingKey: "ordering_key",
		Attributes:  map[string]string{"attr": "value"},
	}
	fakeResponse := &wire.MessageMetadata{
		Partition: 2,
		Offset:    42,
	}
	wantResultID := "2:42"

	for _, tc := range []struct {
		desc string
		// mutateSettings is passed a copy of DefaultPublishSettings to mutate.
		mutateSettings func(settings *PublishSettings)
		wantMsg        *pb.PubSubMessage
	}{
		{
			desc:           "default settings",
			mutateSettings: func(settings *PublishSettings) {},
			wantMsg: &pb.PubSubMessage{
				Data: []byte("data"),
				Key:  []byte("ordering_key"),
				Attributes: map[string]*pb.AttributeValues{
					"attr": {Values: [][]byte{[]byte("value")}},
				},
			},
		},
		{
			desc: "custom key extractor",
			mutateSettings: func(settings *PublishSettings) {
				settings.KeyExtractor = func(msg *pubsub.Message) []byte {
					return msg.Data
				}
			},
			wantMsg: &pb.PubSubMessage{
				Data: []byte("data"),
				Key:  []byte("data"),
				Attributes: map[string]*pb.AttributeValues{
					"attr": {Values: [][]byte{[]byte("value")}},
				},
			},
		},
		{
			desc: "custom message transformer",
			mutateSettings: func(settings *PublishSettings) {
				settings.KeyExtractor = func(msg *pubsub.Message) []byte {
					return msg.Data
				}
				settings.MessageTransformer = func(from *pubsub.Message, to *pb.PubSubMessage) error {
					// Swaps data and key.
					to.Data = []byte(from.OrderingKey)
					to.Key = from.Data
					return nil
				}
			},
			wantMsg: &pb.PubSubMessage{
				Data: []byte("ordering_key"),
				Key:  []byte("data"),
			},
		},
	} {
		t.Run(tc.desc, func(t *testing.T) {
			settings := DefaultPublishSettings
			tc.mutateSettings(&settings)

			verifier := test.NewRPCVerifier(t)
			verifier.Push(tc.wantMsg, fakeResponse, nil)
			defer verifier.Flush()

			pubClient := newTestPublisherClient(verifier, settings)
			result := pubClient.Publish(ctx, input)

			gotID, err := result.Get(ctx)
			if err != nil {
				t.Errorf("Publish() got err: %v", err)
			}
			if gotID != wantResultID {
				t.Errorf("Publish() got id: %q, want: %q", gotID, wantResultID)
			}
		})
	}
}

func TestPublisherClientTransformMessageError(t *testing.T) {
	wantErr := errors.New("message could not be converted")

	settings := DefaultPublishSettings
	settings.MessageTransformer = func(_ *pubsub.Message, _ *pb.PubSubMessage) error {
		return wantErr
	}

	// No publish calls expected.
	verifier := test.NewRPCVerifier(t)
	defer verifier.Flush()

	ctx := context.Background()
	input := &pubsub.Message{
		Data: []byte("data"),
	}
	pubClient := newTestPublisherClient(verifier, settings)
	result := pubClient.Publish(ctx, input)

	_, gotErr := result.Get(ctx)
	if !test.ErrorEqual(gotErr, wantErr) {
		t.Errorf("Publish() got err: (%v), want err: (%v)", gotErr, wantErr)
	}
	if !test.ErrorEqual(pubClient.Error(), wantErr) {
		t.Errorf("PublisherClient.Error() got: (%v), want: (%v)", pubClient.Error(), wantErr)
	}
	if got, want := pubClient.wirePub.(*mockWirePublisher).Stopped, true; got != want {
		t.Errorf("Publisher.Stopped: got %v, want %v", got, want)
	}
}
