// +build integration

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

import (
	"context"
	"fmt"
	"github.com/google/uuid"
	tu "github.com/opencord/voltha-go/tests/utils"
	"github.com/opencord/voltha-lib-go/v2/pkg/log"
	"github.com/opencord/voltha-protos/v2/go/common"
	"github.com/opencord/voltha-protos/v2/go/voltha"
	"github.com/stretchr/testify/assert"
	"google.golang.org/grpc/metadata"
	"math"
	"os"
	"testing"
	"time"
)

var stub voltha.VolthaServiceClient
var volthaSerialNumberKey string

/*
 This local "integration" test uses one RW-Core, one simulated_olt and one simulated_onu adapter to test performance
metrics, in a development environment. It uses docker-compose to set up the local environment. However, it can
easily be extended to run in k8s environment.

The compose files used are located under %GOPATH/src/github.com/opencord/voltha-go/compose. If the GOPATH is not set
then you can specify the location of the compose files by using COMPOSE_PATH to set the compose files location.

To run this test: DOCKER_HOST_IP=<local IP> go test -v

*/

var allDevices map[string]*voltha.Device
var allLogicalDevices map[string]*voltha.LogicalDevice

var composePath string

const (
	GRPC_PORT        = 50057
	NUM_OLTS         = 1
	NUM_ONUS_PER_OLT = 4 // This should coincide with the number of onus per olt in adapters-simulated.yml file
)

var parentPmNames = []string{
	"tx_64_pkts",
	"tx_65_127_pkts",
	"tx_128_255_pkts",
	"tx_256_511_pkts",
	"tx_512_1023_pkts",
	"tx_1024_1518_pkts",
	"tx_1519_9k_pkts",
	"rx_64_pkts",
	"rx_65_127_pkts",
	"rx_128_255_pkts",
	"rx_256_511_pkts",
	"rx_512_1023_pkts",
	"rx_1024_1518_pkts",
	"rx_1519_9k_pkts",
}

var childPmNames = []string{
	"tx_64_pkts",
	"tx_65_127_pkts",
	"tx_128_255_pkts",
	"tx_1024_1518_pkts",
	"tx_1519_9k_pkts",
	"rx_64_pkts",
	"rx_64_pkts",
	"rx_65_127_pkts",
	"rx_128_255_pkts",
	"rx_1024_1518_pkts",
	"rx_1519_9k_pkts",
}

func setup() {
	var err error

	if _, err = log.AddPackage(log.JSON, log.WarnLevel, log.Fields{"instanceId": "testing"}); err != nil {
		log.With(log.Fields{"error": err}).Fatal("Cannot setup logging")
	}
	log.UpdateAllLoggers(log.Fields{"instanceId": "testing"})
	log.SetAllLogLevel(log.ErrorLevel)

	volthaSerialNumberKey = "voltha_serial_number"
	allDevices = make(map[string]*voltha.Device)
	allLogicalDevices = make(map[string]*voltha.LogicalDevice)

	grpcHostIP := os.Getenv("DOCKER_HOST_IP")
	goPath := os.Getenv("GOPATH")
	if goPath != "" {
		composePath = fmt.Sprintf("%s/src/github.com/opencord/voltha-go/compose", goPath)
	} else {
		composePath = os.Getenv("COMPOSE_PATH")
	}

	fmt.Println("Using compose path:", composePath)

	//Start the simulated environment
	if err = tu.StartSimulatedEnv(composePath); err != nil {
		fmt.Println("Failure starting simulated environment:", err)
		os.Exit(10)
	}

	stub, err = tu.SetupGrpcConnectionToCore(grpcHostIP, GRPC_PORT)
	if err != nil {
		fmt.Println("Failure connecting to Voltha Core:", err)
		os.Exit(11)
	}

	// Wait for the simulated devices to be registered in the Voltha Core
	adapters := []string{"simulated_olt", "simulated_onu"}
	if _, err = tu.WaitForAdapterRegistration(stub, adapters, 40); err != nil {
		fmt.Println("Failure retrieving adapters:", err)
		os.Exit(12)
	}
}

func shutdown() {
	err := tu.StopSimulatedEnv(composePath)
	if err != nil {
		fmt.Println("Failure stop simulated environment:", err)
	}
}

func refreshLocalDeviceCache(stub voltha.VolthaServiceClient) error {
	retrievedDevices, err := tu.ListDevices(stub)
	if err != nil {
		return err
	}
	for _, d := range retrievedDevices.Items {
		allDevices[d.Id] = d
	}

	retrievedLogicalDevices, err := tu.ListLogicalDevices(stub)
	if err != nil {
		return err
	}

	for _, ld := range retrievedLogicalDevices.Items {
		allLogicalDevices[ld.Id] = ld
	}
	return nil
}

func isPresent(pmName string, pmNames []string) bool {
	for _, name := range pmNames {
		if name == pmName {
			return true
		}
	}
	return false
}

func verifyDevicePMs(t *testing.T, stub voltha.VolthaServiceClient, device *voltha.Device, allPmNames []string, disabledPmNames []string, frequency uint32) {
	ui := uuid.New()
	ctx := metadata.NewOutgoingContext(context.Background(), metadata.Pairs(volthaSerialNumberKey, ui.String()))
	pmConfigs, err := stub.ListDevicePmConfigs(ctx, &common.ID{Id: device.Id})
	assert.Nil(t, err)
	assert.Equal(t, device.Id, pmConfigs.Id)
	assert.Equal(t, uint32(frequency), pmConfigs.DefaultFreq)
	assert.Equal(t, false, pmConfigs.FreqOverride)
	assert.Equal(t, false, pmConfigs.Grouped)
	assert.Nil(t, pmConfigs.Groups)
	assert.True(t, len(pmConfigs.Metrics) > 0)
	metrics := pmConfigs.Metrics
	for _, m := range metrics {
		if m.Enabled {
			assert.True(t, isPresent(m.Name, allPmNames))
		} else {
			assert.True(t, isPresent(m.Name, disabledPmNames))
		}
		assert.Equal(t, voltha.PmConfig_COUNTER, m.Type)
	}
}

func verifyInitialPmConfigs(t *testing.T, stub voltha.VolthaServiceClient) {
	fmt.Println("Verifying initial PM configs")
	err := refreshLocalDeviceCache(stub)
	assert.Nil(t, err)
	for _, d := range allDevices {
		if d.Root {
			verifyDevicePMs(t, stub, d, parentPmNames, []string{}, 150)
		} else {
			verifyDevicePMs(t, stub, d, childPmNames, []string{}, 150)
		}
	}
}

func verifyPmFrequencyUpdate(t *testing.T, stub voltha.VolthaServiceClient, device *voltha.Device) {
	ui := uuid.New()
	ctx := metadata.NewOutgoingContext(context.Background(), metadata.Pairs(volthaSerialNumberKey, ui.String()))
	pmConfigs, err := stub.ListDevicePmConfigs(ctx, &common.ID{Id: device.Id})
	assert.Nil(t, err)
	pmConfigs.DefaultFreq = 10
	_, err = stub.UpdateDevicePmConfigs(ctx, pmConfigs)
	assert.Nil(t, err)
	if device.Root {
		verifyDevicePMs(t, stub, device, parentPmNames, []string{}, 10)
	} else {
		verifyDevicePMs(t, stub, device, childPmNames, []string{}, 10)
	}
}

func updatePmFrequencies(t *testing.T, stub voltha.VolthaServiceClient) {
	fmt.Println("Verifying update to PMs frequencies")
	err := refreshLocalDeviceCache(stub)
	assert.Nil(t, err)
	for _, d := range allDevices {
		verifyPmFrequencyUpdate(t, stub, d)
	}
}

func verifyDisablingSomePmMetrics(t *testing.T, stub voltha.VolthaServiceClient, device *voltha.Device) {
	ui := uuid.New()
	ctx := metadata.NewOutgoingContext(context.Background(), metadata.Pairs(volthaSerialNumberKey, ui.String()))
	pmConfigs, err := stub.ListDevicePmConfigs(ctx, &common.ID{Id: device.Id})
	assert.Nil(t, err)
	metricsToDisable := []string{"tx_64_pkts", "rx_64_pkts", "tx_65_127_pkts", "rx_65_127_pkts"}
	for _, m := range pmConfigs.Metrics {
		if isPresent(m.Name, metricsToDisable) {
			m.Enabled = false
		}
	}
	_, err = stub.UpdateDevicePmConfigs(ctx, pmConfigs)
	assert.Nil(t, err)
	if device.Root {
		verifyDevicePMs(t, stub, device, parentPmNames, metricsToDisable, 10)
	} else {
		verifyDevicePMs(t, stub, device, childPmNames, metricsToDisable, 10)
	}
}

func disableSomePmMetrics(t *testing.T, stub voltha.VolthaServiceClient) {
	fmt.Println("Verifying disabling of some PMs")
	err := refreshLocalDeviceCache(stub)
	assert.Nil(t, err)
	for _, d := range allDevices {
		verifyDisablingSomePmMetrics(t, stub, d)
	}
}

func createAndEnableDevices(t *testing.T) {
	err := tu.SetAllLogLevel(stub, voltha.Logging{Level: common.LogLevel_WARNING})
	assert.Nil(t, err)

	err = tu.SetLogLevel(stub, voltha.Logging{Level: common.LogLevel_DEBUG, PackageName: "github.com/opencord/voltha-go/rw_core/core"})
	assert.Nil(t, err)

	startTime := time.Now()

	//Pre-provision the parent device
	oltDevice, err := tu.PreProvisionDevice(stub)
	assert.Nil(t, err)

	fmt.Println("Creation of ", NUM_OLTS, " OLT devices took:", time.Since(startTime))

	startTime = time.Now()

	//Enable all parent device - this will enable the child devices as well as validate the child devices
	err = tu.EnableDevice(stub, oltDevice, NUM_ONUS_PER_OLT)
	assert.Nil(t, err)

	fmt.Println("Enabling of  OLT device took:", time.Since(startTime))

	// Wait until the core and adapters sync up after an enabled
	time.Sleep(time.Duration(math.Max(10, float64(NUM_OLTS*NUM_ONUS_PER_OLT)/2)) * time.Second)

	err = tu.VerifyDevices(stub, NUM_ONUS_PER_OLT)
	assert.Nil(t, err)

	lds, err := tu.VerifyLogicalDevices(stub, oltDevice, NUM_ONUS_PER_OLT)
	assert.Nil(t, err)
	assert.Equal(t, 1, len(lds.Items))
}

func TestPerformanceMetrics(t *testing.T) {
	//1. Test creation and activation of the devices.  This will validate the devices as well as the logical device created/
	createAndEnableDevices(t)

	//	2. Test initial PMs on each device
	verifyInitialPmConfigs(t, stub)

	//	3. Test frequency update of the pmConfigs
	updatePmFrequencies(t, stub)

	//	4. Test disable some PM metrics
	disableSomePmMetrics(t, stub)
}

func TestMain(m *testing.M) {
	setup()
	code := m.Run()
	shutdown()
	os.Exit(code)
}
