/*
 * Copyright 2020-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 Common Logger initialization
package test

import (
	"bufio"
	"context"
	"encoding/json"
	"fmt"
	"os"
	"path/filepath"
	"strings"
	"testing"
	"time"

	ca "github.com/opencord/voltha-protos/v5/go/core_adapter"

	"math/rand"

	"github.com/opencord/voltha-go/rw_core/config"
	cm "github.com/opencord/voltha-go/rw_core/mocks"
	"github.com/opencord/voltha-lib-go/v7/pkg/db/kvstore"
	"github.com/opencord/voltha-lib-go/v7/pkg/log"
	mock_etcd "github.com/opencord/voltha-lib-go/v7/pkg/mocks/etcd"
	"github.com/opencord/voltha-lib-go/v7/pkg/version"
	"github.com/opencord/voltha-protos/v5/go/voltha"
	"github.com/phayes/freeport"
	"github.com/stretchr/testify/assert"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
)

const (
	OltAdapter = iota
	OnuAdapter
)

type AdapterInfo struct {
	TotalReplica    int32
	Vendor          string
	DeviceType      string
	ChildDeviceType string
	ChildVendor     string
}

// prettyPrintDeviceUpdateLog is used just for debugging and exploring the Core logs
func prettyPrintDeviceUpdateLog(inputFile string, deviceID string) {
	file, err := os.Open(filepath.Clean(inputFile))
	if err != nil {
		logger.Fatal(context.Background(), err)
	}
	defer func() {
		if err := file.Close(); err != nil {
			logger.Errorw(context.Background(), "file-close-error", log.Fields{"error": err})
		}
	}()

	var logEntry struct {
		Level       string `json:"level"`
		Ts          string `json:"ts"`
		Caller      string `json:"caller"`
		Msg         string `json:"msg"`
		RPC         string `json:"rpc"`
		DeviceID    string `json:"device-id"`
		RequestedBy string `json:"requested-by"`
		StateChange string `json:"state-change"`
		Status      string `json:"status"`
		Description string `json:"description"`
	}

	scanner := bufio.NewScanner(file)
	fmt.Println("Timestamp\t\t\tDeviceId\t\t\t\tStatus\t\t\tRPC\t\t\tRequestedBy\t\t\tStateChange\t\t\tDescription")
	for scanner.Scan() {
		input := scanner.Text()
		// Look for device update logs only
		if !strings.Contains(input, "device-operation") || !strings.Contains(input, "requested-by") {
			continue
		}
		// Check if deviceID is required
		if deviceID != "" {
			if !strings.Contains(input, deviceID) {
				continue
			}
		}
		if err := json.Unmarshal([]byte(input), &logEntry); err != nil {
			logger.Fatal(context.Background(), err)
		}
		fmt.Println(
			fmt.Sprintf(
				"%s\t%s\t%s\t%-30.30q\t%-16.16s\t%-25.25s\t%s",
				logEntry.Ts,
				logEntry.DeviceID,
				logEntry.Status,
				logEntry.RPC,
				logEntry.RequestedBy,
				logEntry.StateChange,
				logEntry.Description))
	}
}

func omciLog(inputFile string, deviceID string) {
	file, err := os.Open(filepath.Clean(inputFile))
	if err != nil {
		logger.Fatal(context.Background(), err)
	}
	defer func() {
		if err := file.Close(); err != nil {
			logger.Errorw(context.Background(), "file-close-error", log.Fields{"error": err})
		}
	}()

	var logEntry struct {
		Level         string `json:"level"`
		Ts            string `json:"ts"`
		Caller        string `json:"caller"`
		Msg           string `json:"msg"`
		InstanceID    string `json:"instanceId"`
		ChildDeviceID string `json:"child-device-id"`
		OmciMsg       string `json:"omciMsg"`
		IntfID        string `json:"intf-id"`
		OnuID         string `json:"onu-id"`
		OmciTrns      int    `json:"omciTransactionID"`
	}

	scanner := bufio.NewScanner(file)
	uniqueTnsIDs := map[int]int{}
	for scanner.Scan() {
		input := scanner.Text()
		// Look for device update logs only
		if !strings.Contains(input, "sent-omci-msg") {
			continue
		}
		// Check if deviceID is required
		if deviceID != "" {
			if !strings.Contains(input, deviceID) {
				continue
			}
		}
		if err := json.Unmarshal([]byte(input), &logEntry); err != nil {
			logger.Fatal(context.Background(), err)
		}
		uniqueTnsIDs[logEntry.OmciTrns]++
	}
	repeatedTrnsID := []int{}
	for k, v := range uniqueTnsIDs {
		if v != 1 {
			repeatedTrnsID = append(repeatedTrnsID, k)
		}
	}
	fmt.Println("RepeatedIDs", repeatedTrnsID, "TransID:", len(uniqueTnsIDs))
}

//CreateMockAdapter creates mock OLT and ONU adapters - this will automatically the grpc service hosted by that
// adapter
func CreateMockAdapter(
	ctx context.Context,
	adapterType int,
	coreEndpoint string,
	deviceType string,
	vendor string,
	childDeviceType string,
	childVendor string,
) (interface{}, error) {

	var adpt interface{}
	switch adapterType {
	case OltAdapter:
		adpt = cm.NewOLTAdapter(ctx, coreEndpoint, deviceType, vendor, childDeviceType, childVendor)
	case OnuAdapter:
		adpt = cm.NewONUAdapter(ctx, coreEndpoint, deviceType, vendor)
	default:
		logger.Fatalf(ctx, "invalid-adapter-type-%d", adapterType)
	}
	return adpt, nil
}

//CreateAndRegisterAdapters creates mock ONU and OLT adapters and registers them to rw-core
func CreateAndRegisterAdapters(
	ctx context.Context,
	t *testing.T,
	oltAdapters map[string]*AdapterInfo,
	onuAdapters map[string]*AdapterInfo,
	coreEndpoint string,
) (map[string][]*cm.OLTAdapter, map[string][]*cm.ONUAdapter) {
	// Setup the ONU adapter first in this unit test environment.  This makes it easier to test whether the
	// Core is ready to send grpc requests to the adapters.  The unit test uses grpc to communicate with the
	// Core and as such it does not have inside knowledge when the adapters are ready.

	// Setup the ONU Adapters
	onuAdaptersMap := make(map[string][]*cm.ONUAdapter)
	for adapterType, adapterInfo := range onuAdapters {
		for replica := int32(1); replica <= adapterInfo.TotalReplica; replica++ {
			adpt, err := CreateMockAdapter(ctx, OnuAdapter, coreEndpoint, adapterInfo.DeviceType, adapterInfo.Vendor, adapterInfo.ChildDeviceType, adapterInfo.ChildVendor)
			assert.Nil(t, err)
			onuAdapter, ok := adpt.(*cm.ONUAdapter)
			assert.True(t, ok)
			assert.NotNil(t, onuAdapter)
			//	Register the adapter
			adapterID := fmt.Sprintf("%s-%d", adapterType, replica)
			adapterToRegister := &voltha.Adapter{
				Id:             adapterID,
				Vendor:         adapterInfo.Vendor,
				Version:        version.VersionInfo.Version,
				Type:           adapterType,
				CurrentReplica: replica,
				TotalReplicas:  adapterInfo.TotalReplica,
				Endpoint:       onuAdapter.GetEndPoint(),
			}
			types := []*voltha.DeviceType{{Id: adapterInfo.DeviceType, AdapterType: adapterType, AcceptsAddRemoveFlowUpdates: true}}
			deviceTypes := &voltha.DeviceTypes{Items: types}
			coreClient, err := onuAdapter.GetCoreClient()
			assert.Nil(t, err)
			assert.NotNil(t, coreClient)
			if _, err := coreClient.RegisterAdapter(ctx, &ca.AdapterRegistration{
				Adapter: adapterToRegister,
				DTypes:  deviceTypes}); err != nil {
				logger.Errorw(ctx, "failed-to-register-adapter", log.Fields{"error": err, "adapter": adapterToRegister.Id})
				assert.NotNil(t, err)
			}
			if _, ok := onuAdaptersMap[adapterType]; !ok {
				onuAdaptersMap[adapterType] = []*cm.ONUAdapter{}
			}
			onuAdaptersMap[adapterType] = append(onuAdaptersMap[adapterType], onuAdapter)
		}
	}

	// Setup the OLT Adapters
	oltAdaptersMap := make(map[string][]*cm.OLTAdapter)
	for adapterType, adapterInfo := range oltAdapters {
		for replica := int32(1); replica <= adapterInfo.TotalReplica; replica++ {
			adpt, err := CreateMockAdapter(ctx, OltAdapter, coreEndpoint, adapterInfo.DeviceType, adapterInfo.Vendor, adapterInfo.ChildDeviceType, adapterInfo.ChildVendor)
			assert.Nil(t, err)
			oltAdapter, ok := adpt.(*cm.OLTAdapter)
			assert.True(t, ok)
			assert.NotNil(t, oltAdapter)

			//	Register the adapter
			adapterID := fmt.Sprintf("%s-%d", adapterType, replica)
			adapterToRegister := &voltha.Adapter{
				Id:             adapterID,
				Vendor:         adapterInfo.Vendor,
				Version:        version.VersionInfo.Version,
				Type:           adapterType,
				CurrentReplica: replica,
				TotalReplicas:  adapterInfo.TotalReplica,
				Endpoint:       oltAdapter.GetEndPoint(),
			}
			types := []*voltha.DeviceType{{Id: adapterInfo.DeviceType, AdapterType: adapterType, AcceptsAddRemoveFlowUpdates: true}}
			deviceTypes := &voltha.DeviceTypes{Items: types}
			coreClient, err := oltAdapter.GetCoreClient()
			assert.Nil(t, err)
			assert.NotNil(t, coreClient)

			if _, err := coreClient.RegisterAdapter(ctx, &ca.AdapterRegistration{
				Adapter: adapterToRegister,
				DTypes:  deviceTypes}); err != nil {
				logger.Errorw(ctx, "failed-to-register-adapter", log.Fields{"error": err, "adapter": adapterToRegister.Id})
				assert.NotNil(t, err)
			}
			if _, ok := oltAdaptersMap[adapterType]; !ok {
				oltAdaptersMap[adapterType] = []*cm.OLTAdapter{}
			}
			oltAdaptersMap[adapterType] = append(oltAdaptersMap[adapterType], oltAdapter)
		}
	}

	return oltAdaptersMap, onuAdaptersMap
}

//StartEmbeddedEtcdServer creates and starts an Embedded etcd server locally.
func StartEmbeddedEtcdServer(ctx context.Context, configName, storageDir, logLevel string) (*mock_etcd.EtcdServer, int, error) {
	kvClientPort, err := freeport.GetFreePort()
	if err != nil {
		return nil, 0, err
	}
	peerPort, err := freeport.GetFreePort()
	if err != nil {
		return nil, 0, err
	}
	etcdServer := mock_etcd.StartEtcdServer(ctx, mock_etcd.MKConfig(ctx, configName, kvClientPort, peerPort, storageDir, logLevel))
	if etcdServer == nil {
		return nil, 0, status.Error(codes.Internal, "Embedded server failed to start")
	}
	return etcdServer, kvClientPort, nil
}

//StopEmbeddedEtcdServer stops the embedded etcd server
func StopEmbeddedEtcdServer(ctx context.Context, server *mock_etcd.EtcdServer) {
	if server != nil {
		server.Stop(ctx)
	}
}

//SetupKVClient creates a new etcd client
func SetupKVClient(ctx context.Context, cf *config.RWCoreFlags, coreInstanceID string) kvstore.Client {
	client, err := kvstore.NewEtcdClient(ctx, cf.KVStoreAddress, cf.KVStoreTimeout, log.FatalLevel)
	if err != nil {
		panic("no kv client")
	}
	return client
}

//getRandomMacAddress returns a random mac address
func getRandomMacAddress() string {
	rand.Seed(time.Now().UnixNano() / int64(rand.Intn(255)+1))
	return fmt.Sprintf("%02x:%02x:%02x:%02x:%02x:%02x",
		rand.Intn(255),
		rand.Intn(255),
		rand.Intn(255),
		rand.Intn(255),
		rand.Intn(255),
		rand.Intn(255),
	)
}
