/*
 * Portions copyright 2019-present Open Networking Foundation
 * Original 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"
	"errors"
	"fmt"
	"github.com/fullstorydev/grpcurl"
	"github.com/golang/protobuf/proto"
	"github.com/golang/protobuf/protoc-gen-go/descriptor"
	"github.com/jhump/protoreflect/desc"
	"github.com/jhump/protoreflect/dynamic"
	"google.golang.org/grpc"
	"io"
	"strconv"
	"strings"
	"time"
)

// Flags for calling the *WithRetry methods
const GM_QUIET = 1
const GM_UNTIL_FOUND = 2
const GM_UNTIL_ENACTED = 4
const GM_UNTIL_STATUS = 8

type QueryEventHandler struct {
	RpcEventHandler
	Elements map[string]string
	Model    *desc.MessageDescriptor
	Kind     string
	EOF      bool
}

// Separate the operator from the query value.
// For example,
//    "==foo"  --> "EQUAL", "foo"
func DecodeOperator(query string) (string, string, bool, error) {
	if strings.HasPrefix(query, "!=") {
		return query[2:], "EQUAL", true, nil
	} else if strings.HasPrefix(query, "==") {
		return "", "", false, errors.New("Operator == is now allowed. Suggest using = instead.")
	} else if strings.HasPrefix(query, "=") {
		return query[1:], "EQUAL", false, nil
	} else if strings.HasPrefix(query, ">=") {
		return query[2:], "GREATER_THAN_OR_EQUAL", false, nil
	} else if strings.HasPrefix(query, ">") {
		return query[1:], "GREATER_THAN", false, nil
	} else if strings.HasPrefix(query, "<=") {
		return query[2:], "LESS_THAN_OR_EQUAL", false, nil
	} else if strings.HasPrefix(query, "<") {
		return query[1:], "LESS_THAN", false, nil
	} else {
		return query, "EQUAL", false, nil
	}
}

// Generate the parameters for Query messages.
func (h *QueryEventHandler) GetParams(msg proto.Message) error {
	dmsg, err := dynamic.AsDynamicMessage(msg)
	if err != nil {
		return err
	}

	//fmt.Printf("MessageName: %s\n", dmsg.XXX_MessageName())

	if h.EOF {
		return io.EOF
	}

	// Get the MessageType for the `elements` field
	md := dmsg.GetMessageDescriptor()
	elements_fld := md.FindFieldByName("elements")
	elements_mt := elements_fld.GetMessageType()

	for field_name, element := range h.Elements {
		value, operator, invert, err := DecodeOperator(element)
		if err != nil {
			return err
		}

		nm := dynamic.NewMessage(elements_mt)

		field_type := h.Model.FindFieldByName(field_name).GetType()
		if field_type == descriptor.FieldDescriptorProto_TYPE_INT32 {
			i, _ := strconv.ParseInt(value, 10, 32)
			nm.SetFieldByName("iValue", int32(i))
		} else if field_type == descriptor.FieldDescriptorProto_TYPE_UINT32 {
			i, _ := strconv.ParseInt(value, 10, 32)
			nm.SetFieldByName("iValue", uint32(i))
		} else {
			nm.SetFieldByName("sValue", value)
		}

		nm.SetFieldByName("name", field_name)
		nm.SetFieldByName("invert", invert)
		SetEnumValue(nm, "operator", operator)
		dmsg.AddRepeatedFieldByName("elements", nm)
	}

	SetEnumValue(dmsg, "kind", h.Kind)

	h.EOF = true

	return nil
}

// Take a string list of queries and turns it into a map of queries
func QueryStringsToMap(query_args []string) (map[string]string, error) {
	queries := make(map[string]string)
	for _, query_str := range query_args {
		query_str := strings.Trim(query_str, " ")
		operator_pos := -1
		for i, ch := range query_str {
			if (ch == '!') || (ch == '=') || (ch == '>') || (ch == '<') {
				operator_pos = i
				break
			}
		}
		if operator_pos == -1 {
			return nil, fmt.Errorf("Illegal query string %s", query_str)
		}
		queries[query_str[:operator_pos]] = query_str[operator_pos:]
	}
	return queries, nil
}

// Take a string of comma-separated queries and turn it into a map of queries
func CommaSeparatedQueryToMap(query_str string) (map[string]string, error) {
	if query_str == "" {
		return nil, nil
	}

	query_strings := strings.Split(query_str, ",")
	return QueryStringsToMap(query_strings)
}

// Return a list of all available model names
func GetModelNames(source grpcurl.DescriptorSource) (map[string]bool, error) {
	models := make(map[string]bool)
	methods, err := grpcurl.ListMethods(source, "xos.xos")

	if err != nil {
		return nil, err
	}

	for _, method := range methods {
		if strings.HasPrefix(method, "xos.xos.Get") {
			models[method[11:]] = true
		}
	}

	return models, nil
}

// Check to see if a model name is valid
func CheckModelName(source grpcurl.DescriptorSource, name string) error {
	models, err := GetModelNames(source)
	if err != nil {
		return err
	}
	_, present := models[name]
	if !present {
		return errors.New("Model " + name + " does not exist. Use `cordctl models available` to get a list of available models")
	}
	return nil
}

// Create a model in XOS given a map of fields
func CreateModel(conn *grpc.ClientConn, descriptor grpcurl.DescriptorSource, modelName string, fields map[string]interface{}) error {
	ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
	defer cancel()

	headers := GenerateHeaders()

	h := &RpcEventHandler{
		Fields: map[string]map[string]interface{}{"xos." + modelName: fields},
	}
	err := grpcurl.InvokeRPC(ctx, descriptor, conn, "xos.xos.Create"+modelName, headers, h, h.GetParams)
	if err != nil {
		return err
	} else if h.Status != nil && h.Status.Err() != nil {
		return h.Status.Err()
	}

	resp, err := dynamic.AsDynamicMessage(h.Response)
	if err != nil {
		return err
	}

	fields["id"] = resp.GetFieldByName("id").(int32)

	if resp.HasFieldName("uuid") {
		fields["uuid"] = resp.GetFieldByName("uuid").(string)
	}

	return nil
}

// Get a model from XOS given its ID
func GetModel(conn *grpc.ClientConn, descriptor grpcurl.DescriptorSource, modelName string, id int32) (*dynamic.Message, error) {
	ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
	defer cancel()

	headers := GenerateHeaders()

	h := &RpcEventHandler{
		Fields: map[string]map[string]interface{}{"xos.ID": map[string]interface{}{"id": id}},
	}
	err := grpcurl.InvokeRPC(ctx, descriptor, conn, "xos.xos.Get"+modelName, headers, h, h.GetParams)
	if err != nil {
		return nil, err
	}

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

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

	return d, nil
}

// Get a model, but retry under a variety of circumstances
func GetModelWithRetry(conn *grpc.ClientConn, descriptor grpcurl.DescriptorSource, modelName string, id int32, flags uint32) (*grpc.ClientConn, *dynamic.Message, error) {
	quiet := (flags & GM_QUIET) != 0
	until_found := (flags & GM_UNTIL_FOUND) != 0
	until_enacted := (flags & GM_UNTIL_ENACTED) != 0
	until_status := (flags & GM_UNTIL_STATUS) != 0

	for {
		var err error

		if conn == nil {
			conn, err = NewConnection()
			if err != nil {
				return nil, nil, err
			}
		}

		model, err := GetModel(conn, descriptor, modelName, id)
		if err != nil {
			if strings.Contains(err.Error(), "rpc error: code = Unavailable") ||
				strings.Contains(err.Error(), "rpc error: code = Internal desc = stream terminated by RST_STREAM") {
				if !quiet {
					fmt.Print(".")
				}
				time.Sleep(100 * time.Millisecond)
				conn.Close()
				conn = nil
				continue
			}

			if until_found && strings.Contains(err.Error(), "rpc error: code = NotFound") {
				if !quiet {
					fmt.Print("x")
				}
				time.Sleep(100 * time.Millisecond)
				continue
			}
			return nil, nil, err
		}

		if until_enacted && !IsEnacted(model) {
			if !quiet {
				fmt.Print("o")
			}
			time.Sleep(100 * time.Millisecond)
			continue
		}

		if until_status && model.GetFieldByName("status") == nil {
			if !quiet {
				fmt.Print("O")
			}
			time.Sleep(100 * time.Millisecond)
			continue
		}

		return conn, model, nil
	}
}

func ItemsToDynamicMessageList(items interface{}) []*dynamic.Message {
	result := make([]*dynamic.Message, len(items.([]interface{})))
	for i, item := range items.([]interface{}) {
		result[i] = item.(*dynamic.Message)
	}
	return result
}

// List all objects of a given model
func ListModels(conn *grpc.ClientConn, descriptor grpcurl.DescriptorSource, modelName string) ([]*dynamic.Message, error) {
	ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
	defer cancel()

	headers := GenerateHeaders()

	h := &RpcEventHandler{}
	err := grpcurl.InvokeRPC(ctx, descriptor, conn, "xos.xos.List"+modelName, headers, h, h.GetParams)
	if err != nil {
		return nil, err
	}

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

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

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

	return ItemsToDynamicMessageList(items), nil
}

// Filter models based on field values
//   queries is a map of <field_name> to <operator><query>
//   For example,
//     map[string]string{"name": "==mysite"}
func FilterModels(conn *grpc.ClientConn, descriptor grpcurl.DescriptorSource, modelName string, queries map[string]string) ([]*dynamic.Message, error) {
	ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
	defer cancel()

	headers := GenerateHeaders()

	model_descriptor, err := descriptor.FindSymbol("xos." + modelName)
	if err != nil {
		return nil, err
	}
	model_md, ok := model_descriptor.(*desc.MessageDescriptor)
	if !ok {
		return nil, errors.New("Failed to convert model to a messagedescriptor")
	}

	h := &QueryEventHandler{
		RpcEventHandler: RpcEventHandler{
			Fields: map[string]map[string]interface{}{"xos.Query": map[string]interface{}{"kind": 0}},
		},
		Elements: queries,
		Model:    model_md,
		Kind:     "DEFAULT",
	}
	err = grpcurl.InvokeRPC(ctx, descriptor, conn, "xos.xos.Filter"+modelName, headers, h, h.GetParams)
	if err != nil {
		return nil, err
	}

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

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

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

	return ItemsToDynamicMessageList(items), nil
}

// Get a model from XOS given a fieldName/fieldValue
func FindModel(conn *grpc.ClientConn, descriptor grpcurl.DescriptorSource, modelName string, queries map[string]string) (*dynamic.Message, error) {
	models, err := FilterModels(conn, descriptor, modelName, queries)
	if err != nil {
		return nil, err
	}

	if len(models) == 0 {
		return nil, errors.New("rpc error: code = NotFound")
	}

	return models[0], nil
}

// Find a model, but retry under a variety of circumstances
func FindModelWithRetry(conn *grpc.ClientConn, descriptor grpcurl.DescriptorSource, modelName string, queries map[string]string, flags uint32) (*grpc.ClientConn, *dynamic.Message, error) {
	quiet := (flags & GM_QUIET) != 0
	until_found := (flags & GM_UNTIL_FOUND) != 0
	until_enacted := (flags & GM_UNTIL_ENACTED) != 0
	until_status := (flags & GM_UNTIL_STATUS) != 0

	for {
		var err error

		if conn == nil {
			conn, err = NewConnection()
			if err != nil {
				return nil, nil, err
			}
		}

		model, err := FindModel(conn, descriptor, modelName, queries)
		if err != nil {
			if strings.Contains(err.Error(), "rpc error: code = Unavailable") ||
				strings.Contains(err.Error(), "rpc error: code = Internal desc = stream terminated by RST_STREAM") {
				if !quiet {
					fmt.Print(".")
				}
				time.Sleep(100 * time.Millisecond)
				conn.Close()
				conn = nil
				continue
			}

			if until_found && strings.Contains(err.Error(), "rpc error: code = NotFound") {
				if !quiet {
					fmt.Print("x")
				}
				time.Sleep(100 * time.Millisecond)
				continue
			}
			return nil, nil, err
		}

		if until_enacted && !IsEnacted(model) {
			if !quiet {
				fmt.Print("o")
			}
			time.Sleep(100 * time.Millisecond)
			continue
		}

		if until_status && model.GetFieldByName("status") == nil {
			if !quiet {
				fmt.Print("O")
			}
			time.Sleep(100 * time.Millisecond)
			continue
		}

		return conn, model, nil
	}
}

// Takes a *dynamic.Message and turns it into a map of fields to interfaces
//    TODO: Might be more useful to convert the values to strings and ints
func MessageToMap(d *dynamic.Message) map[string]interface{} {
	fields := make(map[string]interface{})
	for _, field_desc := range d.GetKnownFields() {
		field_name := field_desc.GetName()
		fields[field_name] = d.GetFieldByName(field_name)
	}
	return fields
}

// Returns True if a message has been enacted
func IsEnacted(d *dynamic.Message) bool {
	enacted := d.GetFieldByName("enacted").(float64)
	updated := d.GetFieldByName("updated").(float64)

	return (enacted >= updated)
}
