/*
 * Copyright 2020-present Open Networking Foundation

 * 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 events

import (
	"context"
	"strconv"
	"testing"
	"time"

	"github.com/opencord/voltha-lib-go/v7/pkg/kafka"
	"github.com/opencord/voltha-lib-go/v7/pkg/log"
	mock_kafka "github.com/opencord/voltha-lib-go/v7/pkg/mocks/kafka"
	"github.com/opencord/voltha-protos/v5/go/common"
	"github.com/opencord/voltha-protos/v5/go/voltha"
	"github.com/stretchr/testify/assert"
)

const waitForKafkaEventsTimeout = 20 * time.Second
const waitForEventProxyTimeout = 10 * time.Second

func waitForEventProxyToStop(ep *EventProxy, resp chan string) {
	timer := time.NewTimer(waitForEventProxyTimeout)
	defer timer.Stop()
	for {
		select {
		case <-time.After(2 * time.Millisecond):
			if ep.eventQueue.insertPosition == nil {
				resp <- "ok"
				return
			}
		case <-timer.C:
			resp <- "timer expired"
			return
		}

	}
}
func waitForKafkaEvents(kc kafka.Client, topic *kafka.Topic, numEvents int, resp chan string) {
	kafkaChnl, err := kc.Subscribe(context.Background(), topic)
	if err != nil {
		resp <- err.Error()
		return
	}
	defer func() {
		if kafkaChnl != nil {
			if err = kc.UnSubscribe(context.Background(), topic, kafkaChnl); err != nil {
				logger.Errorw(context.Background(), "unsubscribe-failed", log.Fields{"error": err})
			}
		}
	}()
	timer := time.NewTimer(waitForKafkaEventsTimeout)
	defer timer.Stop()
	count := 0
loop:
	for {
		select {
		case msg := <-kafkaChnl:
			if _, ok := msg.(*voltha.Event); ok {
				count += 1
				if count == numEvents {
					resp <- "ok"
					break loop
				}
			}
		case <-timer.C:
			resp <- "timer expired"
			break loop
		}
	}
}

func createAndSendEvent(proxy *EventProxy, id string) error {
	eventMsg := &voltha.RPCEvent{
		Rpc:         "dummy",
		OperationId: id,
		ResourceId:  "dummy",
		Service:     "dummy",
		StackId:     "dummy",
		Status: &common.OperationResp{
			Code: common.OperationResp_OPERATION_FAILURE,
		},
		Description: "dummy",
		Context:     nil,
	}
	var event voltha.Event
	raisedTS := time.Now().Unix()
	event.Header, _ = proxy.getEventHeader("RPC_ERROR_RAISE_EVENT", voltha.EventCategory_COMMUNICATION, nil, voltha.EventType_RPC_EVENT, raisedTS)
	event.EventType = &voltha.Event_RpcEvent{RpcEvent: eventMsg}
	err := proxy.SendRPCEvent(context.Background(), "RPC_ERROR_RAISE_EVENT", eventMsg, voltha.EventCategory_COMMUNICATION,
		nil, time.Now().Unix())
	return err
}

func TestEventProxyReceiveAndSendMessage(t *testing.T) {
	// Init Kafka client
	log.SetAllLogLevel(log.FatalLevel)
	cTkc := mock_kafka.NewKafkaClient()
	topic := kafka.Topic{Name: "myTopic"}

	numEvents := 10
	resp := make(chan string)
	go waitForKafkaEvents(cTkc, &topic, numEvents, resp)

	// Init Event Proxy
	ep := NewEventProxy(MsgClient(cTkc), MsgTopic(topic))
	go func() {
		if err := ep.Start(); err != nil {
			logger.Fatalw(context.Background(), "failure-starting-event-proxy", log.Fields{"error": err})
		}
	}()
	time.Sleep(1 * time.Millisecond)
	for i := 0; i < numEvents; i++ {
		go func(ID int) {
			err := createAndSendEvent(ep, strconv.Itoa(ID))
			assert.Nil(t, err)
		}(i)
	}
	val := <-resp
	assert.Equal(t, val, "ok")
	go ep.Stop()
	go waitForEventProxyToStop(ep, resp)
	val = <-resp
	assert.Equal(t, val, "ok")
}

func TestEventProxyStopWhileSendingEvents(t *testing.T) {
	// Init Kafka client
	log.SetAllLogLevel(log.FatalLevel)
	cTkc := mock_kafka.NewKafkaClient()
	topic := kafka.Topic{Name: "myTopic"}

	numEvents := 10
	resp := make(chan string)
	// Init Event Proxy
	ep := NewEventProxy(MsgClient(cTkc), MsgTopic(topic))
	go func() {
		if err := ep.Start(); err != nil {
			logger.Fatalw(context.Background(), "failure-starting-event-proxy", log.Fields{"error": err})
		}
	}()
	time.Sleep(1 * time.Millisecond)
	for i := 0; i < numEvents; i++ {
		go func(ID int) {
			err := createAndSendEvent(ep, strconv.Itoa(ID))
			assert.Nil(t, err)
		}(i)
	}
	// In this case we cannot guarantee how many events are send before
	// sending the last event(stopping event proxy), any event send before Stop would be received.
	go ep.Stop()
	go waitForEventProxyToStop(ep, resp)
	val := <-resp
	assert.Equal(t, val, "ok")
}

func TestEventProxyStopWhenNoEventsSend(t *testing.T) {
	// Init Kafka client
	log.SetAllLogLevel(log.FatalLevel)
	cTkc := mock_kafka.NewKafkaClient()
	topic := kafka.Topic{Name: "myTopic"}
	resp := make(chan string)
	// Init Event Proxy
	ep := NewEventProxy(MsgClient(cTkc), MsgTopic(topic))
	go func() {
		if err := ep.Start(); err != nil {
			logger.Fatalw(context.Background(), "failure-starting-event-proxy", log.Fields{"error": err})
		}
	}()
	time.Sleep(1 * time.Millisecond)
	go ep.Stop()
	go waitForEventProxyToStop(ep, resp)
	val := <-resp
	assert.Equal(t, val, "ok")
}
