/*
 * Copyright 2019-present Ciena Corporation
 *
 * 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 commands

import (
	"context"
	"fmt"
	"github.com/fullstorydev/grpcurl"
	flags "github.com/jessevdk/go-flags"
	"github.com/jhump/protoreflect/dynamic"
	"github.com/opencord/voltctl/pkg/format"
	"github.com/opencord/voltctl/pkg/model"
	"google.golang.org/grpc"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
	"strings"
)

type SetLogLevelOutput struct {
	ComponentName string
	Status        string
	Error         string
}

type SetLogLevelOpts struct {
	OutputOptions
	Package string `short:"p" long:"package" description:"Package name to set log level"`
	Args    struct {
		Level     string
		Component []string
	} `positional-args:"yes" required:"yes"`
}

type GetLogLevelsOpts struct {
	ListOutputOptions
	Args struct {
		Component []string
	} `positional-args:"yes" required:"yes"`
}

type ListLogLevelsOpts struct {
	ListOutputOptions
}

type LogLevelOpts struct {
	SetLogLevel   SetLogLevelOpts   `command:"set"`
	GetLogLevels  GetLogLevelsOpts  `command:"get"`
	ListLogLevels ListLogLevelsOpts `command:"list"`
}

var logLevelOpts = LogLevelOpts{}

const (
	DEFAULT_LOGLEVELS_FORMAT   = "table{{ .ComponentName }}\t{{.PackageName}}\t{{.Level}}"
	DEFAULT_SETLOGLEVEL_FORMAT = "table{{ .ComponentName }}\t{{.Status}}\t{{.Error}}"
)

func RegisterLogLevelCommands(parent *flags.Parser) {
	_, err := parent.AddCommand("loglevel", "loglevel commands", "Get and set log levels", &logLevelOpts)
	if err != nil {
		panic(err)
	}
}

func MapListAppend(m map[string][]string, name string, item string) {
	list, okay := m[name]
	if okay {
		m[name] = append(list, item)
	} else {
		m[name] = []string{item}
	}
}

/*
 * A roundabout way of going of using the LogLevel enum to map from
 * a string to an integer that we can pass into the dynamic
 * proto.
 *
 * TODO: There's probably an easier way.
 */
func LogLevelStringToInt(logLevelString string) (int32, error) {
	ProcessGlobalOptions() // required for GetMethod()

	/*
	 * Use GetMethod() to get us a descriptor on the proto file we're
	 * interested in.
	 */

	descriptor, _, err := GetMethod("update-log-level")
	if err != nil {
		return 0, err
	}

	/*
	 * Map string LogLevel to enumerated type LogLevel
	 * We have descriptor from above, which is a DescriptorSource
	 * We can use FindSymbol to get at the message
	 */

	loggingSymbol, err := descriptor.FindSymbol("common.LogLevel")
	if err != nil {
		return 0, err
	}

	/*
	 * LoggingSymbol is a Descriptor, but not a MessageDescrptior,
	 * so we can't look at it's fields yet. Go back to the file,
	 * call FindMessage to get the Message, then we can get the
	 * embedded enum.
	 */

	loggingFile := loggingSymbol.GetFile()
	logLevelMessage := loggingFile.FindMessage("common.LogLevel")
	logLevelEnumType := logLevelMessage.GetNestedEnumTypes()[0]
	enumLogLevel := logLevelEnumType.FindValueByName(logLevelString)

	if enumLogLevel == nil {
		return 0, fmt.Errorf("Unknown log level %s", logLevelString)
	}

	return enumLogLevel.GetNumber(), nil
}

// Validate a list of component names and throw an error if any one of them is bad.
func ValidateComponentNames(kube_to_arouter map[string][]string, names []string) error {
	var badNames []string
	for _, name := range names {
		_, ok := kube_to_arouter[name]
		if !ok {
			badNames = append(badNames, name)
		}
	}

	if len(badNames) > 0 {
		allowedNames := make([]string, len(kube_to_arouter))
		i := 0
		for k := range kube_to_arouter {
			allowedNames[i] = k
			i++
		}

		return fmt.Errorf("Unknown component(s): %s.\n  (Allowed values for component names: \n    %s)",
			strings.Join(badNames, ", "),
			strings.Join(allowedNames, ",\n    "))
	} else {
		return nil
	}
}

func BuildKubernetesNameMap() (map[string][]string, map[string]string, error) {
	kube_to_arouter := make(map[string][]string)
	arouter_to_kube := make(map[string]string)

	// use the current context in kubeconfig
	config, err := clientcmd.BuildConfigFromFlags("", GlobalOptions.K8sConfig)
	if err != nil {
		return nil, nil, err
	}

	// create the clientset
	clientset, err := kubernetes.NewForConfig(config)
	if err != nil {
		return nil, nil, err
	}

	pods, err := clientset.CoreV1().Pods("").List(metav1.ListOptions{
		LabelSelector: "app.kubernetes.io/part-of=voltha",
	})
	if err != nil {
		return nil, nil, err
	}

	if len(pods.Items) == 0 {
		return nil, nil, fmt.Errorf("No Voltha pods found in Kubernetes -- verify pod is setup")
	}

	for _, pod := range pods.Items {
		app, ok := pod.Labels["app"]
		if !ok {
			continue
		}

		var arouter_name string

		switch app {
		case "voltha-api-server":
			/*
			 * Assumes a single api_server for now.
			 * TODO: Make labeling changes in charts to be able to derive name from labels
			 */
			arouter_name = "api_server0.api_server01"
		case "rw-core":
			affinity_group, ok := pod.Labels["affinity-group"]
			if !ok {
				Warn.Printf("rwcore %s lacks affinity-group label", pod.Name)
				continue
			}
			affinity_group_core_id, ok := pod.Labels["affinity-group-core-id"]
			if !ok {
				Warn.Printf("rwcore %s lacks affinity-group-core-id label", pod.Name)
				continue
			}
			arouter_name = "vcore" + affinity_group + ".vcore" + affinity_group + affinity_group_core_id
		case "ro-core":
			/*
			 * Assumes a single rocore for now.
			 * TODO: Make labeling changes in charts to be able to derive name from labels
			 */
			arouter_name = "ro_vcore0.ro_vcore01"
		default:
			// skip this pod as it's not relevant
			continue
		}

		// Multiple ways to identify the component

		// 1) The pod name. One pod name maps to exactly one pod.

		arouter_to_kube[arouter_name] = pod.Name
		MapListAppend(kube_to_arouter, pod.Name, arouter_name)

		// 2) The kubernetes component name. A single component (i.e. "core") may map to multiple pods.

		component, ok := pod.Labels["app.kubernetes.io/component"]
		if ok {
			MapListAppend(kube_to_arouter, component, arouter_name)
		}

		// 3) The voltha app label. A single app (i.e. "rwcore") may map to multiple pods.

		MapListAppend(kube_to_arouter, app, arouter_name)

	}

	return kube_to_arouter, arouter_to_kube, nil
}

func (options *SetLogLevelOpts) Execute(args []string) error {
	if len(options.Args.Component) == 0 {
		return fmt.Errorf("Please specify at least one component")
	}

	kube_to_arouter, arouter_to_kube, err := BuildKubernetesNameMap()
	if err != nil {
		return err
	}

	var output []SetLogLevelOutput

	// Validate component names, throw error now to avoid doing partial work
	err = ValidateComponentNames(kube_to_arouter, options.Args.Component)
	if err != nil {
		return err
	}

	// Validate and map the logLevel string to an integer, throw error now to avoid doing partial work
	intLogLevel, err := LogLevelStringToInt(options.Args.Level)
	if err != nil {
		return err
	}

	for _, kubeComponentName := range options.Args.Component {
		var descriptor grpcurl.DescriptorSource
		var conn *grpc.ClientConn
		var method string

		componentNameList := kube_to_arouter[kubeComponentName]

		for _, componentName := range componentNameList {
			conn, err = NewConnection()
			if err != nil {
				return err
			}
			defer conn.Close()
			if strings.HasPrefix(componentName, "api_server") {
				// apiserver's UpdateLogLevel is in the afrouter.Configuration gRPC package
				descriptor, method, err = GetMethod("apiserver-update-log-level")
			} else {
				descriptor, method, err = GetMethod("update-log-level")
			}
			if err != nil {
				return err
			}

			ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
			defer cancel()

			ll := make(map[string]interface{})
			ll["component_name"] = componentName
			ll["package_name"] = options.Package
			ll["level"] = intLogLevel

			h := &RpcEventHandler{
				Fields: map[string]map[string]interface{}{"common.Logging": ll},
			}
			err = grpcurl.InvokeRPC(ctx, descriptor, conn, method, []string{}, h, h.GetParams)
			if err != nil {
				return err
			}

			if h.Status != nil && h.Status.Err() != nil {
				output = append(output, SetLogLevelOutput{ComponentName: arouter_to_kube[componentName], Status: "Failure", Error: h.Status.Err().Error()})
				continue
			}

			output = append(output, SetLogLevelOutput{ComponentName: arouter_to_kube[componentName], Status: "Success"})
		}
	}

	outputFormat := CharReplacer.Replace(options.Format)
	if outputFormat == "" {
		outputFormat = GetCommandOptionWithDefault("loglevel-set", "format", DEFAULT_SETLOGLEVEL_FORMAT)
	}

	result := CommandResult{
		Format:    format.Format(outputFormat),
		OutputAs:  toOutputType(options.OutputAs),
		NameLimit: options.NameLimit,
		Data:      output,
	}

	GenerateOutput(&result)
	return nil
}

func (options *GetLogLevelsOpts) getLogLevels(methodName string, args []string) error {
	if len(options.Args.Component) == 0 {
		return fmt.Errorf("Please specify at least one component")
	}

	kube_to_arouter, arouter_to_kube, err := BuildKubernetesNameMap()
	if err != nil {
		return err
	}

	var data []model.LogLevel

	// Validate component names, throw error now to avoid doing partial work
	err = ValidateComponentNames(kube_to_arouter, options.Args.Component)
	if err != nil {
		return err
	}

	for _, kubeComponentName := range options.Args.Component {
		var descriptor grpcurl.DescriptorSource
		var conn *grpc.ClientConn
		var method string

		componentNameList := kube_to_arouter[kubeComponentName]

		for _, componentName := range componentNameList {
			conn, err = NewConnection()
			if err != nil {
				return err
			}
			defer conn.Close()
			if strings.HasPrefix(componentName, "api_server") {
				// apiserver's UpdateLogLevel is in the afrouter.Configuration gRPC package
				descriptor, method, err = GetMethod("apiserver-get-log-levels")
			} else {
				descriptor, method, err = GetMethod("get-log-levels")
			}
			if err != nil {
				return err
			}

			ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
			defer cancel()

			ll := make(map[string]interface{})
			ll["component_name"] = componentName

			h := &RpcEventHandler{
				Fields: map[string]map[string]interface{}{"common.LoggingComponent": ll},
			}
			err = grpcurl.InvokeRPC(ctx, descriptor, conn, method, []string{}, h, h.GetParams)
			if err != nil {
				return err
			}

			if h.Status != nil && h.Status.Err() != nil {
				return h.Status.Err()
			}

			d, err := dynamic.AsDynamicMessage(h.Response)
			if err != nil {
				return err
			}
			items, err := d.TryGetFieldByName("items")
			if err != nil {
				return err
			}

			for _, item := range items.([]interface{}) {
				logLevel := model.LogLevel{}
				logLevel.PopulateFrom(item.(*dynamic.Message))
				logLevel.ComponentName = arouter_to_kube[logLevel.ComponentName]

				data = append(data, logLevel)
			}
		}
	}

	outputFormat := CharReplacer.Replace(options.Format)
	if outputFormat == "" {
		outputFormat = GetCommandOptionWithDefault(methodName, "format", DEFAULT_LOGLEVELS_FORMAT)
	}
	orderBy := options.OrderBy
	if orderBy == "" {
		orderBy = GetCommandOptionWithDefault(methodName, "order", "")
	}

	result := CommandResult{
		Format:    format.Format(outputFormat),
		Filter:    options.Filter,
		OrderBy:   orderBy,
		OutputAs:  toOutputType(options.OutputAs),
		NameLimit: options.NameLimit,
		Data:      data,
	}
	GenerateOutput(&result)
	return nil
}

func (options *GetLogLevelsOpts) Execute(args []string) error {
	return options.getLogLevels("loglevel-get", args)
}

func (options *ListLogLevelsOpts) Execute(args []string) error {
	var getOptions GetLogLevelsOpts
	var podNames []string

	_, arouter_to_kube, err := BuildKubernetesNameMap()
	if err != nil {
		return err
	}

	for _, podName := range arouter_to_kube {
		podNames = append(podNames, podName)
	}

	// Just call GetLogLevels with a list of podnames that includes everything relevant.

	getOptions.ListOutputOptions = options.ListOutputOptions
	getOptions.Args.Component = podNames

	return getOptions.getLogLevels("loglevel-list", args)
}
