/*
 * 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"
	"github.com/opencord/bbsim/api/bbsim"
	"github.com/opencord/bbsim/internal/bbsim/devices"
	"strconv"
)

func convertBBSimServiceToProtoService(s *devices.Service) *bbsim.Service {
	return &bbsim.Service{
		Name:          s.Name,
		InternalState: s.InternalState.Current(),
		HwAddress:     s.HwAddress.String(),
		OnuSn:         s.UniPort.Onu.Sn(),
		UniId:         s.UniPort.ID,
		CTag:          int32(s.CTag),
		STag:          int32(s.STag),
		NeedsEapol:    s.NeedsEapol,
		NeedsDhcp:     s.NeedsDhcp,
		NeedsIgmp:     s.NeedsIgmp,
		GemPort:       int32(s.GemPort),
		EapolState:    s.EapolState.Current(),
		DhcpState:     s.DHCPState.Current(),
		IGMPState:     s.IGMPState.Current(),
	}
}

func convertBBsimServicesToProtoServices(list []devices.ServiceIf) []*bbsim.Service {
	services := []*bbsim.Service{}
	for _, service := range list {
		s := service.(*devices.Service)
		services = append(services, convertBBSimServiceToProtoService(s))
	}
	return services
}

func (s BBSimServer) GetServices(ctx context.Context, req *bbsim.UNIRequest) (*bbsim.Services, error) {

	services := bbsim.Services{
		Items: []*bbsim.Service{},
	}

	olt := devices.GetOLT()

	for _, pon := range olt.Pons {
		for _, o := range pon.Onus {
			for _, u := range o.UniPorts {
				uni := u.(*devices.UniPort)
				s := convertBBsimServicesToProtoServices(uni.Services)
				for _, service := range s {
					intVar, err := strconv.Atoi(req.UniID)
					if req.UniID == "" && req.OnuSerialNumber == "" {
						services.Items = append(services.Items, s...)
					} else if err == nil && service.UniId == uint32(intVar) && service.OnuSn == req.OnuSerialNumber {
						services.Items = append(services.Items, s...)
					} else if req.UniID == "" && service.OnuSn == req.OnuSerialNumber {
						services.Items = append(services.Items, s...)
					}
				}
			}
		}
	}

	return &services, nil
}
