/*
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements.  See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You 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 consumer

import (
	"path/filepath"
	"testing"

	"github.com/apache/rocketmq-client-go/v2/internal"
	"github.com/apache/rocketmq-client-go/v2/internal/remote"
	"github.com/apache/rocketmq-client-go/v2/primitive"
	"github.com/golang/mock/gomock"
	. "github.com/smartystreets/goconvey/convey"
)

func TestNewLocalFileOffsetStore(t *testing.T) {
	Convey("Given some test cases", t, func() {
		type testCase struct {
			clientId       string
			group          string
			expectedResult *localFileOffsetStore
		}
		cases := []testCase{
			{
				clientId: "",
				group:    "testGroup",
				expectedResult: &localFileOffsetStore{
					group: "testGroup",
					path:  filepath.Join(_LocalOffsetStorePath, "/testGroup/offset.json"),
				},
			}, {
				clientId: "192.168.24.1@default",
				group:    "",
				expectedResult: &localFileOffsetStore{
					group: "",
					path:  filepath.Join(_LocalOffsetStorePath, "/192.168.24.1@default/offset.json"),
				},
			}, {
				clientId: "192.168.24.1@default",
				group:    "testGroup",
				expectedResult: &localFileOffsetStore{
					group: "testGroup",
					path:  filepath.Join(_LocalOffsetStorePath, "/192.168.24.1@default/testGroup/offset.json"),
				},
			},
		}

		for _, value := range cases {
			result := NewLocalFileOffsetStore(value.clientId, value.group).(*localFileOffsetStore)
			value.expectedResult.OffsetTable = result.OffsetTable
			So(result, ShouldResemble, value.expectedResult)
		}
	})
}

func TestLocalFileOffsetStore(t *testing.T) {
	Convey("Given a local store with a starting value", t, func() {
		localStore := NewLocalFileOffsetStore("192.168.24.1@default", "testGroup")

		type offsetCase struct {
			queue          *primitive.MessageQueue
			setOffset      int64
			expectedOffset int64
		}
		mq := &primitive.MessageQueue{
			Topic:      "testTopic",
			BrokerName: "default",
			QueueId:    1,
		}

		Convey("test update", func() {
			Convey("when increaseOnly is false", func() {
				cases := []offsetCase{
					{
						queue:          mq,
						setOffset:      3,
						expectedOffset: 3,
					}, {
						queue:          mq,
						setOffset:      1,
						expectedOffset: 1,
					},
				}
				for _, value := range cases {
					localStore.update(value.queue, value.setOffset, false)
					offset, _ := localStore.readWithException(value.queue, _ReadFromMemory)
					So(offset, ShouldEqual, value.expectedOffset)
				}
			})

			Convey("when increaseOnly is true", func() {
				localStore.update(mq, 0, false)

				cases := []offsetCase{
					{
						queue:          mq,
						setOffset:      3,
						expectedOffset: 3,
					}, {
						queue:          mq,
						setOffset:      1,
						expectedOffset: 3,
					},
				}
				for _, value := range cases {
					localStore.update(value.queue, value.setOffset, true)
					offset, _ := localStore.readWithException(value.queue, _ReadFromMemory)
					So(offset, ShouldEqual, value.expectedOffset)
				}
			})
		})

		Convey("test persist", func() {
			localStore.update(mq, 1, false)
			offset, _ := localStore.readWithException(mq, _ReadFromMemory)
			So(offset, ShouldEqual, 1)

			queues := []*primitive.MessageQueue{mq}
			localStore.persist(queues)
			offset, _ = localStore.readWithException(mq, _ReadFromStore)
			So(offset, ShouldEqual, 1)

			localStore.(*localFileOffsetStore).OffsetTable.Delete(MessageQueueKey(*mq))
			offset, _ = localStore.readWithException(mq, _ReadMemoryThenStore)
			So(offset, ShouldEqual, 1)
		})
	})
}

func TestRemoteBrokerOffsetStore(t *testing.T) {
	Convey("Given a remote store with a starting value", t, func() {
		ctrl := gomock.NewController(t)
		defer ctrl.Finish()

		namesrv := internal.NewMockNamesrvs(ctrl)

		rmqClient := internal.NewMockRMQClient(ctrl)
		remoteStore := NewRemoteOffsetStore("testGroup", rmqClient, namesrv)

		type offsetCase struct {
			queue          *primitive.MessageQueue
			setOffset      int64
			expectedOffset int64
		}
		mq := &primitive.MessageQueue{
			Topic:      "testTopic",
			BrokerName: "default",
			QueueId:    1,
		}

		Convey("test update", func() {
			Convey("when increaseOnly is false", func() {
				cases := []offsetCase{
					{
						queue:          mq,
						setOffset:      3,
						expectedOffset: 3,
					}, {
						queue:          mq,
						setOffset:      1,
						expectedOffset: 1,
					},
				}
				for _, value := range cases {
					remoteStore.update(value.queue, value.setOffset, false)
					offset, _ := remoteStore.readWithException(value.queue, _ReadFromMemory)
					So(offset, ShouldEqual, value.expectedOffset)
				}
			})

			Convey("when increaseOnly is true", func() {
				remoteStore.update(mq, 0, false)

				cases := []offsetCase{
					{
						queue:          mq,
						setOffset:      3,
						expectedOffset: 3,
					}, {
						queue:          mq,
						setOffset:      1,
						expectedOffset: 3,
					},
				}
				for _, value := range cases {
					remoteStore.update(value.queue, value.setOffset, true)
					offset, _ := remoteStore.readWithException(value.queue, _ReadFromMemory)
					So(offset, ShouldEqual, value.expectedOffset)
				}
			})
		})

		Convey("test persist", func() {
			queues := []*primitive.MessageQueue{mq}

			namesrv.EXPECT().FindBrokerAddrByName(gomock.Any()).Return("192.168.24.1:10911").MaxTimes(2)

			ret := &remote.RemotingCommand{
				Code: internal.ResSuccess,
				ExtFields: map[string]string{
					"offset": "1",
				},
			}
			rmqClient.EXPECT().InvokeSync(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(ret, nil).MaxTimes(2)

			remoteStore.persist(queues)
			offset, _ := remoteStore.readWithException(mq, _ReadFromStore)
			So(offset, ShouldEqual, 1)

			remoteStore.remove(mq)
			offset, _ = remoteStore.readWithException(mq, _ReadFromMemory)
			So(offset, ShouldEqual, -1)
			offset, _ = remoteStore.readWithException(mq, _ReadMemoryThenStore)
			So(offset, ShouldEqual, 1)

		})

		Convey("test remove", func() {
			remoteStore.update(mq, 1, false)
			offset, _ := remoteStore.readWithException(mq, _ReadFromMemory)
			So(offset, ShouldEqual, 1)

			remoteStore.remove(mq)
			offset, _ = remoteStore.readWithException(mq, _ReadFromMemory)
			So(offset, ShouldEqual, -1)
		})
	})
}
