/*
 * Copyright 2018-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 api

import (
	"context"
	"fmt"
	"google.golang.org/grpc/status"
	"strings"
	"time"

	"github.com/opencord/bbsim/api/bbsim"
	"github.com/opencord/bbsim/internal/bbsim/devices"
	"github.com/opencord/bbsim/internal/common"
	log "github.com/sirupsen/logrus"
	"google.golang.org/grpc/codes"
)

var logger = log.WithFields(log.Fields{
	"module": "GrpcApiServer",
})

var (
	version    string
	buildTime  string
	commitHash string
	gitStatus  string
)

type BBSimServer struct {
}

func (s BBSimServer) Version(ctx context.Context, req *bbsim.Empty) (*bbsim.VersionNumber, error) {
	// TODO add a flag to specify whether the tree was clean at this commit or not
	return &bbsim.VersionNumber{
		Version:    version,
		BuildTime:  buildTime,
		CommitHash: commitHash,
		GitStatus:  gitStatus,
	}, nil
}

func (s BBSimServer) GetOlt(ctx context.Context, req *bbsim.Empty) (*bbsim.Olt, error) {
	olt := devices.GetOLT()
	nnis := []*bbsim.NNIPort{}
	pons := []*bbsim.PONPort{}

	for _, nni := range olt.Nnis {
		n := bbsim.NNIPort{
			ID:        int32(nni.ID),
			OperState: nni.OperState.Current(),
		}
		nnis = append(nnis, &n)
	}

	for _, pon := range olt.Pons {

		allocatedOnuIds := []*bbsim.PonAllocatedResources{}
		allocatedAllocIds := []*bbsim.PonAllocatedResources{}
		allocatedGemPorts := []*bbsim.PonAllocatedResources{}

		for k, v := range pon.AllocatedOnuIds {
			resource := &bbsim.PonAllocatedResources{
				SerialNumber: common.OnuSnToString(v),
				Id:           int32(k),
			}
			allocatedOnuIds = append(allocatedOnuIds, resource)
		}

		for k, v := range pon.AllocatedGemPorts {
			resource := &bbsim.PonAllocatedResources{
				SerialNumber: common.OnuSnToString(v),
				Id:           int32(k),
			}
			allocatedGemPorts = append(allocatedGemPorts, resource)
		}

		for _, v := range pon.AllocatedAllocIds {
			resource := &bbsim.PonAllocatedResources{
				SerialNumber: common.OnuSnToString(v.OnuSn),
				Id:           int32(v.AllocID),
			}
			allocatedAllocIds = append(allocatedAllocIds, resource)
		}

		p := bbsim.PONPort{
			ID:                int32(pon.ID),
			OperState:         pon.OperState.Current(),
			InternalState:     pon.InternalState.Current(),
			PacketCount:       pon.PacketCount,
			AllocatedOnuIds:   allocatedOnuIds,
			AllocatedAllocIds: allocatedAllocIds,
			AllocatedGemPorts: allocatedGemPorts,
		}
		pons = append(pons, &p)
	}

	oltAddress := strings.Split(common.Config.BBSim.OpenOltAddress, ":")[0]
	if oltAddress == "" {
		oltAddress = getOltIP().String()
	}

	res := bbsim.Olt{
		ID:            int32(olt.ID),
		SerialNumber:  olt.SerialNumber,
		OperState:     olt.OperState.Current(),
		InternalState: olt.InternalState.Current(),
		IP:            oltAddress,
		NNIPorts:      nnis,
		PONPorts:      pons,
	}
	return &res, nil
}

// takes a nested map and return a proto
func resourcesMapToresourcesProto(resourceType bbsim.OltAllocatedResourceType_Type, resources map[uint32]map[uint32]map[uint32]map[int32]map[uint64]bool) *bbsim.OltAllocatedResources {
	proto := &bbsim.OltAllocatedResources{
		Resources: []*bbsim.OltAllocatedResource{},
	}
	for ponId, ponValues := range resources {
		for onuId, onuValues := range ponValues {
			for uniId, uniValues := range onuValues {
				for allocId, flows := range uniValues {
					for flow := range flows {
						resource := &bbsim.OltAllocatedResource{
							Type:       resourceType.String(),
							PonPortId:  ponId,
							OnuId:      onuId,
							PortNo:     uniId,
							ResourceId: allocId,
							FlowId:     flow,
						}
						proto.Resources = append(proto.Resources, resource)
					}
				}
			}
		}
	}
	return proto
}

func (s BBSimServer) GetOltAllocatedResources(ctx context.Context, req *bbsim.OltAllocatedResourceType) (*bbsim.OltAllocatedResources, error) {
	o := devices.GetOLT()

	switch req.Type {
	case bbsim.OltAllocatedResourceType_UNKNOWN:
		return nil, status.Errorf(codes.InvalidArgument, "resource-type-%s-is-invalid", req.Type)
	case bbsim.OltAllocatedResourceType_ALLOC_ID:
		return resourcesMapToresourcesProto(bbsim.OltAllocatedResourceType_ALLOC_ID, o.AllocIDs), nil
	case bbsim.OltAllocatedResourceType_GEM_PORT:
		return resourcesMapToresourcesProto(bbsim.OltAllocatedResourceType_GEM_PORT, o.GemPortIDs), nil
	default:
		return nil, status.Errorf(codes.InvalidArgument, "unkown-resource-type-%s", req.Type)
	}
}

func (s BBSimServer) PoweronOlt(ctx context.Context, req *bbsim.Empty) (*bbsim.Response, error) {
	res := &bbsim.Response{}
	o := devices.GetOLT()

	if err := o.InternalState.Event("initialize"); err != nil {
		log.Errorf("Error initializing OLT: %v", err)
		res.StatusCode = int32(codes.FailedPrecondition)
		return res, err
	}

	res.StatusCode = int32(codes.OK)
	return res, nil
}

func (s BBSimServer) ShutdownOlt(ctx context.Context, req *bbsim.Empty) (*bbsim.Response, error) {
	res := &bbsim.Response{}
	o := devices.GetOLT()

	if err := o.InternalState.Event("disable"); err != nil {
		log.Errorf("Error disabling OLT: %v", err)
		res.StatusCode = int32(codes.FailedPrecondition)
		return res, err
	}

	res.StatusCode = int32(codes.OK)
	return res, nil
}

func (s BBSimServer) RebootOlt(ctx context.Context, req *bbsim.Empty) (*bbsim.Response, error) {
	res := &bbsim.Response{}
	o := devices.GetOLT()
	go func() { _ = o.RestartOLT() }()
	res.StatusCode = int32(codes.OK)
	res.Message = fmt.Sprintf("OLT restart triggered.")
	return res, nil
}

func (s BBSimServer) StopgRPCServer(ctx context.Context, req *bbsim.Empty) (*bbsim.Response, error) {
	res := &bbsim.Response{}
	res.StatusCode = int32(codes.OK)
	res.Message = fmt.Sprintf("Openolt gRPC server stopped")
	o := devices.GetOLT()

	logger.Infof("Received request to stop Openolt gRPC Server")

	o.StopOltServer()

	return res, nil
}

func (s BBSimServer) StartgRPCServer(ctx context.Context, req *bbsim.Empty) (*bbsim.Response, error) {
	res := &bbsim.Response{}
	res.StatusCode = int32(codes.OK)
	res.Message = fmt.Sprintf("Openolt gRPC server started")
	o := devices.GetOLT()

	logger.Infof("Received request to start Openolt gRPC Server")

	if o.OltServer != nil {
		return nil, fmt.Errorf("Openolt gRPC server already running.")
	}

	oltGrpcServer, err := o.StartOltServer()
	if err != nil {
		return nil, err
	}
	o.OltServer = oltGrpcServer

	return res, nil
}

func (s BBSimServer) RestartgRPCServer(ctx context.Context, req *bbsim.Timeout) (*bbsim.Response, error) {
	o := devices.GetOLT()
	logger.Infof("Received request to restart Openolt gRPC Server in %v seconds", req.Delay)
	o.StopOltServer()

	res := &bbsim.Response{}
	res.StatusCode = int32(codes.OK)
	res.Message = fmt.Sprintf("Openolt gRPC server stopped, restarting in %v", req.Delay)

	go func() {
		time.Sleep(time.Duration(req.Delay) * time.Second)
		oltGrpcServer, err := o.StartOltServer()
		if err != nil {
			logger.WithFields(log.Fields{
				"err": err,
			}).Error("Cannot restart Openolt gRPC server")
		}
		o.OltServer = oltGrpcServer
		logger.Infof("Openolt gRPC Server restarted after %v seconds", req.Delay)
	}()

	return res, nil
}

func (s BBSimServer) SetLogLevel(ctx context.Context, req *bbsim.LogLevel) (*bbsim.LogLevel, error) {

	common.SetLogLevel(log.StandardLogger(), req.Level, req.Caller)

	return &bbsim.LogLevel{
		Level:  log.StandardLogger().Level.String(),
		Caller: log.StandardLogger().ReportCaller,
	}, nil
}

func (s BBSimServer) SetOnuAlarmIndication(ctx context.Context, req *bbsim.ONUAlarmRequest) (*bbsim.Response, error) {
	o := devices.GetOLT()

	res := &bbsim.Response{}

	onu, err := o.FindOnuBySn(req.SerialNumber)
	if err != nil {
		res.StatusCode = int32(codes.NotFound)
		res.Message = err.Error()
		return nil, err
	}

	if err := onu.SetAlarm(req.AlarmType, req.Status); err != nil {
		res.StatusCode = int32(codes.Internal)
		res.Message = err.Error()
		return nil, err
	}

	res.StatusCode = int32(codes.OK)
	res.Message = fmt.Sprintf("Onu Alarm Indication Sent.")
	return res, nil
}

// SetOltAlarmIndication generates OLT Alarms for LOS
func (s BBSimServer) SetOltAlarmIndication(ctx context.Context, req *bbsim.OLTAlarmRequest) (*bbsim.Response, error) {
	o := devices.GetOLT()
	res := &bbsim.Response{}

	if err := o.SetAlarm(req.InterfaceID, req.InterfaceType, req.Status); err != nil {
		res.StatusCode = int32(codes.Internal)
		res.Message = err.Error()
		return nil, err
	}

	res.StatusCode = int32(codes.OK)
	res.Message = fmt.Sprintf("Olt Alarm Indication Sent.")
	return res, nil
}
