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

func convertBBSimServiceToProtoService(s *devices.Service) *bbsim.Service {
	return &bbsim.Service{
		Name:          s.Name,
		InternalState: s.InternalState.Current(),
		HwAddress:     s.HwAddress.String(),
		OnuSn:         s.Onu.Sn(),
		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.Empty) (*bbsim.Services, error) {

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

	olt := devices.GetOLT()

	for _, pon := range olt.Pons {
		for _, o := range pon.Onus {
			s := convertBBsimServicesToProtoServices(o.Services)
			services.Items = append(services.Items, s...)
		}
	}

	return &services, nil
}

func (s BBSimServer) GetOnuServices(ctx context.Context, req *bbsim.ONURequest) (*bbsim.Services, error) {
	onu, err := s.GetONU(ctx, req)

	if err != nil {
		return nil, err
	}

	services := bbsim.Services{
		Items: onu.Services,
	}

	return &services, nil
}
