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

// BBR (BBSim Reflector) is a tool designed to scale test BBSim
// It shared most of the code with BBSim itself and replies to messages
// pretending to be VOLTHA.
// The idea behind it is that, given that the BBSim and BBR are based on the same
// codebase, BBR is acting as a wall for BBSim. And you can't beat the wall.
package main

import (
	"os"
	"runtime/pprof"
	"time"

	bbrdevices "github.com/opencord/bbsim/internal/bbr/devices"
	"github.com/opencord/bbsim/internal/bbsim/devices"
	"github.com/opencord/bbsim/internal/common"
	log "github.com/sirupsen/logrus"
)

// usage
func main() {
	config := common.GetBBROpts()

	common.SetLogLevel(log.StandardLogger(), config.BBR.LogLevel, config.BBR.LogCaller)

	if config.LogFile != "" {
		file, err := os.OpenFile(config.LogFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
		if err == nil {
			log.StandardLogger().Out = file
		} else {
			log.Fatal("Failed to log to file, using default stderr")
		}
	}

	if *config.BBSim.CpuProfile != "" {
		// start profiling
		log.Infof("Creating profile file at: %s", *config.BBSim.CpuProfile)
		f, err := os.Create(*config.BBSim.CpuProfile)
		if err != nil {
			log.Fatal(err)
		}
		_ = pprof.StartCPUProfile(f)
	}

	log.WithFields(log.Fields{
		"OltID":        config.Olt.ID,
		"NumNniPerOlt": config.Olt.NniPorts,
		"NumPonPerOlt": config.Olt.PonPorts,
		"NumOnuPerPon": config.Olt.OnusPonPort,
		"BBSimIp":      config.BBSimIp,
		"BBSimPort":    config.BBSimPort,
		"LogLevel":     config.BBR.LogLevel,
		"TotalOnus":    config.Olt.PonPorts * config.Olt.OnusPonPort,
	}).Info("BroadBand Reflector is on")

	// create the OLT device
	olt := devices.CreateOLT(
		*config.GlobalConfig,
		common.Services,
		true,
	)

	onuIdMap := make(map[uint32]uint32, config.Olt.PonPorts)

	oltMock := bbrdevices.OltMock{
		Olt:           olt,
		TargetOnus:    int(config.Olt.PonPorts * config.Olt.OnusPonPort),
		CompletedOnus: 0,
		BBSimIp:       config.BBSimIp,
		BBSimPort:     config.BBSimPort,
		BBSimApiPort:  config.BBSimApiPort,
		LastUsedOnuId: onuIdMap,
	}

	// start the enable sequence
	startTime := time.Now()
	defer func() {
		endTime := time.Now()
		runTime := endTime.Sub(startTime)
		log.WithField("Duration", runTime).Info("BBR done!")
	}()
	oltMock.Start()
}
