/*
* 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"

	"github.com/golang/protobuf/ptypes/empty"
	"google.golang.org/grpc"
)

func (vpa *VPAgent) receivePacketsIn(ctx context.Context) {
	logger.Debug(ctx, "receive-packets-in-started")
	// If we exit, assume disconnected
	defer func() {
		vpa.events <- vpaEventVolthaDisconnected
		logger.Debug(ctx, "receive-packets-in-finished")
	}()
	if vpa.volthaClient == nil {
		logger.Fatal(ctx, "no-voltha-connection")
		return
	}
	opt := grpc.EmptyCallOption{}
	streamCtx, streamDone := context.WithCancel(context.Background())
	defer streamDone()
	stream, err := vpa.volthaClient.Get().ReceivePacketsIn(streamCtx, &empty.Empty{}, opt)
	if err != nil {
		logger.Errorw(ctx, "Unable to establish Receive PacketIn Stream",
			log.Fields{"error": err})
		return
	}

top:

	for {
		select {
		case <-ctx.Done():
			logger.Errorw(ctx, "Context Done", log.Fields{"Context": ctx})
			break top
		default:
			pkt, err := stream.Recv()
			if err == io.EOF {
				stream, err = vpa.volthaClient.Get().ReceivePacketsIn(streamCtx, &empty.Empty{}, opt)
				if err != nil {
					logger.Errorw(ctx, "Unable to establish Receive PacketIn Stream",
						log.Fields{"error": err})
					return
				}
				continue
			}

			if isConnCanceled(err) {
				logger.Errorw(ctx, "error receiving packet",
					log.Fields{"error": err})
				break top
			} else if err != nil {
				logger.Warnw(ctx, "Ignoring unhandled error", log.Fields{"err": err})
				continue
			}
			vpa.packetInChannel <- pkt
		}
	}
}

func (vpa *VPAgent) handlePacketsIn(ctx context.Context) {
	logger.Debug(ctx, "handle-packets-in-started")
top:
	for {
		select {
		case <-ctx.Done():
			logger.Errorw(ctx, "Context Done", log.Fields{"Context": ctx})
			break top
		case packet := <-vpa.packetInChannel:
			if vpc := vpa.getVPClient(packet.Id); vpc != nil {
				vpc.PacketIn(ctx, packet)
			}
		}
	}
	logger.Debug(ctx, "handle-packets-in-finished")
}
