/*
* Copyright 2022-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 vpagent

import (
	"context"
	"io"

	"voltha-go-controller/log"

	"google.golang.org/grpc"
	"google.golang.org/protobuf/types/known/emptypb"
)

func (vpa *VPAgent) receiveChangeEvents(ctx context.Context) {
	logger.Debug(ctx, "receive-change-events-started")
	// If we exit, assume disconnected
	defer func() {
		vpa.events <- vpaEventVolthaDisconnected
		logger.Debug(ctx, "receive-change-events-finished")
	}()
	if vpa.volthaClient == nil {
		logger.Fatal(ctx, "no-voltha-connection")
		return
	}
	opt := grpc.EmptyCallOption{}
	streamCtx, streamDone := context.WithCancel(context.Background())
	defer streamDone()
	vServiceClient := vpa.volthaClient.Get()
	if vServiceClient == nil {
		logger.Error(ctx, "Failed to get Voltha Service Client")
		return
	}

	stream, err := vServiceClient.ReceiveChangeEvents(streamCtx, &emptypb.Empty{}, opt)
	if err != nil {
		logger.Errorw(ctx, "Unable to establish Receive Change Event Stream",
			log.Fields{"error": err})
		return
	}

top:
	for {
		select {
		case <-ctx.Done():
			logger.Errorw(ctx, "Context Done", log.Fields{"Context": ctx})
			break top
		default:
			ce, err := stream.Recv()
			if err == io.EOF {
				stream, err = vServiceClient.ReceiveChangeEvents(streamCtx, &emptypb.Empty{}, opt)
				if err != nil {
					logger.Errorw(ctx, "Unable to establish Receive Change Event Stream",
						log.Fields{"error": err})
					return
				}
				continue
			}
			if isConnCanceled(err) {
				logger.Errorw(ctx, "error receiving change event",
					log.Fields{"error": err})
				break top
			} else if err != nil {
				logger.Warnw(ctx, "Ignoring unhandled error", log.Fields{"err": err})
				continue
			}
			vpa.changeEventChannel <- ce
			logger.Debug(ctx, "receive-change-event-queued")
		}
	}
}

func (vpa *VPAgent) handleChangeEvents(ctx context.Context) {
	logger.Debug(ctx, "handle-change-event-started")

top:
	for {
		select {
		case <-ctx.Done():
			logger.Errorw(ctx, "Context Done", log.Fields{"Context": ctx})
			break top
		case changeEvent := <-vpa.changeEventChannel:
			logger.Debugw(ctx, "Change Event", log.Fields{"Device": changeEvent.Id})
			if vpc := vpa.getVPClient(changeEvent.Id); vpc != nil {
				if err := vpc.ChangeEvent(changeEvent); err != nil {
					logger.Errorw(ctx, "error handling Change Event", log.Fields{"Error": err, "Device": changeEvent.Id})
				}
			}
		}
	}

	logger.Debug(ctx, "handle-change-event-finsihed")
}
