/*
 * 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"
	"fmt"
	"github.com/fullstorydev/grpcurl"
	flags "github.com/jessevdk/go-flags"
	"github.com/jhump/protoreflect/dynamic"
	corderrors "github.com/opencord/cordctl/error"
	"google.golang.org/grpc"
	"sort"
	"strings"
	"time"
)

const (
	DEFAULT_CREATE_FORMAT = "table{{ .Id }}\t{{ .Message }}"
	DEFAULT_DELETE_FORMAT = "table{{ .Id }}\t{{ .Message }}"
	DEFAULT_UPDATE_FORMAT = "table{{ .Id }}\t{{ .Message }}"
	DEFAULT_SYNC_FORMAT   = "table{{ .Id }}\t{{ .Message }}"
)

type ModelNameString string

type ModelList struct {
	ListOutputOptions
	ShowHidden      bool   `long:"showhidden" description:"Show hidden fields in default output"`
	ShowFeedback    bool   `long:"showfeedback" description:"Show feedback fields in default output"`
	ShowBookkeeping bool   `long:"showbookkeeping" description:"Show bookkeeping fields in default output"`
	Filter          string `short:"f" long:"filter" description:"Comma-separated list of filters"`
	State           string `short:"s" long:"state" description:"Filter model state [DEFAULT | ALL | DIRTY | DELETED | DIRTYPOL | DELETEDPOL]"`
	Args            struct {
		ModelName ModelNameString
	} `positional-args:"yes" required:"yes"`
}

type ModelUpdate struct {
	OutputOptions
	Unbuffered  bool          `short:"u" long:"unbuffered" description:"Do not buffer console output and suppress default output processor"`
	Filter      string        `short:"f" long:"filter" description:"Comma-separated list of filters"`
	SetFields   string        `long:"set-field" description:"Comma-separated list of field=value to set"`
	SetJSON     string        `long:"set-json" description:"JSON dictionary to use for settings fields"`
	Sync        bool          `long:"sync" description:"Synchronize before returning"`
	SyncTimeout time.Duration `long:"synctimeout" default:"600s" description:"Timeout for --sync option"`
	Args        struct {
		ModelName ModelNameString
	} `positional-args:"yes" required:"yes"`
	IDArgs struct {
		ID []int32
	} `positional-args:"yes" required:"no"`
}

type ModelDelete struct {
	OutputOptions
	Unbuffered bool   `short:"u" long:"unbuffered" description:"Do not buffer console output and suppress default output processor"`
	Filter     string `short:"f" long:"filter" description:"Comma-separated list of filters"`
	All        bool   `short:"a" long:"all" description:"Operate on all models"`
	Args       struct {
		ModelName ModelNameString
	} `positional-args:"yes" required:"yes"`
	IDArgs struct {
		ID []int32
	} `positional-args:"yes" required:"no"`
}

type ModelCreate struct {
	OutputOptions
	Unbuffered  bool          `short:"u" long:"unbuffered" description:"Do not buffer console output"`
	SetFields   string        `long:"set-field" description:"Comma-separated list of field=value to set"`
	SetJSON     string        `long:"set-json" description:"JSON dictionary to use for settings fields"`
	Sync        bool          `long:"sync" description:"Synchronize before returning"`
	SyncTimeout time.Duration `long:"synctimeout" default:"600s" description:"Timeout for --sync option"`
	Args        struct {
		ModelName ModelNameString
	} `positional-args:"yes" required:"yes"`
}

type ModelSync struct {
	OutputOptions
	Unbuffered  bool          `short:"u" long:"unbuffered" description:"Do not buffer console output and suppress default output processor"`
	Filter      string        `short:"f" long:"filter" description:"Comma-separated list of filters"`
	SyncTimeout time.Duration `long:"synctimeout" default:"600s" description:"Timeout for synchronization"`
	All         bool          `short:"a" long:"all" description:"Operate on all models"`
	Args        struct {
		ModelName ModelNameString
	} `positional-args:"yes" required:"yes"`
	IDArgs struct {
		ID []int32
	} `positional-args:"yes" required:"no"`
}

type ModelSetDirty struct {
	OutputOptions
	Unbuffered bool   `short:"u" long:"unbuffered" description:"Do not buffer console output and suppress default output processor"`
	Filter     string `short:"f" long:"filter" description:"Comma-separated list of filters"`
	All        bool   `short:"a" long:"all" description:"Operate on all models"`
	Args       struct {
		ModelName ModelNameString
	} `positional-args:"yes" required:"yes"`
	IDArgs struct {
		ID []int32
	} `positional-args:"yes" required:"no"`
}

type ModelOpts struct {
	List     ModelList     `command:"list"`
	Update   ModelUpdate   `command:"update"`
	Delete   ModelDelete   `command:"delete"`
	Create   ModelCreate   `command:"create"`
	Sync     ModelSync     `command:"sync"`
	SetDirty ModelSetDirty `command:"setdirty"`
}

type ModelStatusOutputRow struct {
	Id      interface{} `json:"id"`
	Message string      `json:"message"`
}

type ModelStatusOutput struct {
	Rows       []ModelStatusOutputRow
	Unbuffered bool
}

var modelOpts = ModelOpts{}

func RegisterModelCommands(parser *flags.Parser) {
	parser.AddCommand("model", "model commands", "Commands to query and manipulate XOS models", &modelOpts)
}

// Initialize ModelStatusOutput structure, creating a row for each model that will be output
func InitModelStatusOutput(unbuffered bool, count int) ModelStatusOutput {
	return ModelStatusOutput{Rows: make([]ModelStatusOutputRow, count), Unbuffered: unbuffered}
}

// Update model status output row for the model
//    If unbuffered is set then we will output directly to the console. Regardless of the unbuffered
//    setting, we always update the row, as callers may check that row for status.
// Args:
//    output - ModelStatusOutput struct to update
//    i - index of row to update
//    id - id of model, <nil> if no model exists
//    status - status text to set if there is no error
//    errror - if non-nil, then apply error text instead of status text
//    final - true if successful status should be reported, false if successful status is yet to come

func UpdateModelStatusOutput(output *ModelStatusOutput, i int, id interface{}, status string, err error, final bool) {
	if err != nil {
		if output.Unbuffered {
			fmt.Printf("%v: %s\n", id, err)
		}
		output.Rows[i] = ModelStatusOutputRow{Id: id, Message: err.Error()}
	} else {
		if output.Unbuffered && final {
			fmt.Println(id)
		}
		output.Rows[i] = ModelStatusOutputRow{Id: id, Message: status}
	}
}

// Convert a user-supplied state filter argument to the appropriate enum name
func GetFilterKind(kindArg string) (string, error) {
	kindMap := map[string]string{
		"default":   FILTER_DEFAULT,
		"all":       FILTER_ALL,
		"dirty":     FILTER_DIRTY,
		"deleted":   FILTER_DELETED,
		"dirtypol":  FILTER_DIRTYPOL,
		"deletedpo": FILTER_DELETEDPOL,
	}

	// If no arg then use default
	if kindArg == "" {
		return kindMap["default"], nil
	}

	val, ok := kindMap[strings.ToLower(kindArg)]
	if !ok {
		return "", corderrors.WithStackTrace(&corderrors.UnknownModelStateError{Name: kindArg})
	}

	return val, nil
}

// Common processing for commands that take a modelname and a list of ids or a filter
func GetIDList(conn *grpc.ClientConn, descriptor grpcurl.DescriptorSource, modelName string, ids []int32, filter string, all bool) ([]int32, error) {
	err := CheckModelName(descriptor, modelName)
	if err != nil {
		return nil, err
	}

	// we require exactly one of ID, --filter, or --all
	exclusiveCount := 0
	if len(ids) > 0 {
		exclusiveCount++
	}
	if filter != "" {
		exclusiveCount++
	}
	if all {
		exclusiveCount++
	}

	if (exclusiveCount == 0) || (exclusiveCount > 1) {
		return nil, corderrors.WithStackTrace(&corderrors.FilterRequiredError{})
	}

	queries, err := CommaSeparatedQueryToMap(filter, true)
	if err != nil {
		return nil, err
	}

	if len(ids) > 0 {
		// do nothing
	} else {
		models, err := ListOrFilterModels(context.Background(), conn, descriptor, modelName, FILTER_DEFAULT, queries)
		if err != nil {
			return nil, err
		}
		ids = make([]int32, len(models))
		for i, model := range models {
			ids[i] = model.GetFieldByName("id").(int32)
		}
		if len(ids) == 0 {
			return nil, corderrors.WithStackTrace(&corderrors.NoMatchError{})
		} else if len(ids) > 1 {
			if !Confirmf("Filter matches %d objects. Continue [y/n] ? ", len(models)) {
				return nil, corderrors.WithStackTrace(&corderrors.AbortedError{})
			}
		}
	}

	return ids, nil
}

func (options *ModelList) Execute(args []string) error {
	conn, descriptor, err := InitClient(INIT_DEFAULT)
	if err != nil {
		return err
	}

	defer conn.Close()

	err = CheckModelName(descriptor, string(options.Args.ModelName))
	if err != nil {
		return err
	}

	filterKind, err := GetFilterKind(options.State)
	if err != nil {
		return err
	}

	queries, err := CommaSeparatedQueryToMap(options.Filter, true)
	if err != nil {
		return err
	}

	models, err := ListOrFilterModels(context.Background(), conn, descriptor, string(options.Args.ModelName), filterKind, queries)
	if err != nil {
		return err
	}

	var field_names []string
	data := make([]map[string]interface{}, len(models))
	for i, val := range models {
		data[i] = make(map[string]interface{})
		for _, field_desc := range val.GetKnownFields() {
			field_name := field_desc.GetName()

			isGuiHidden := strings.Contains(field_desc.GetFieldOptions().String(), "1005:1")
			isFeedback := strings.Contains(field_desc.GetFieldOptions().String(), "1006:1")
			isBookkeeping := strings.Contains(field_desc.GetFieldOptions().String(), "1007:1")

			if isGuiHidden && (!options.ShowHidden) {
				continue
			}

			if isFeedback && (!options.ShowFeedback) {
				continue
			}

			if isBookkeeping && (!options.ShowBookkeeping) {
				continue
			}

			if field_desc.IsRepeated() {
				continue
			}

			data[i][field_name] = val.GetFieldByName(field_name)

			// Every row has the same set of known field names, so it suffices to use the names
			// from the first row.
			if i == 0 {
				field_names = append(field_names, field_name)
			}
		}
	}

	// Sort field names, making sure "id" appears first
	sort.SliceStable(field_names, func(i, j int) bool {
		if field_names[i] == "id" {
			return true
		} else if field_names[j] == "id" {
			return false
		} else {
			return (field_names[i] < field_names[j])
		}
	})

	var default_format strings.Builder
	default_format.WriteString("table")
	for i, field_name := range field_names {
		if i == 0 {
			fmt.Fprintf(&default_format, "{{ .%s }}", field_name)
		} else {
			fmt.Fprintf(&default_format, "\t{{ .%s }}", field_name)
		}
	}

	FormatAndGenerateListOutput(&options.ListOutputOptions, default_format.String(), "{{.id}}", data)

	return nil
}

func (options *ModelUpdate) Execute(args []string) error {
	conn, descriptor, err := InitClient(INIT_DEFAULT)
	if err != nil {
		return err
	}

	defer conn.Close()

	err = CheckModelName(descriptor, string(options.Args.ModelName))
	if err != nil {
		return err
	}

	if (len(options.IDArgs.ID) == 0 && len(options.Filter) == 0) ||
		(len(options.IDArgs.ID) != 0 && len(options.Filter) != 0) {
		return corderrors.WithStackTrace(&corderrors.FilterRequiredError{})
	}

	queries, err := CommaSeparatedQueryToMap(options.Filter, true)
	if err != nil {
		return err
	}

	updates, err := CommaSeparatedQueryToMap(options.SetFields, true)
	if err != nil {
		return err
	}

	modelName := string(options.Args.ModelName)

	var models []*dynamic.Message

	if len(options.IDArgs.ID) > 0 {
		models = make([]*dynamic.Message, len(options.IDArgs.ID))
		for i, id := range options.IDArgs.ID {
			models[i], err = GetModel(context.Background(), conn, descriptor, modelName, id)
			if err != nil {
				return err
			}
		}
	} else {
		models, err = ListOrFilterModels(context.Background(), conn, descriptor, modelName, FILTER_DEFAULT, queries)
		if err != nil {
			return err
		}
	}

	if len(models) == 0 {
		return corderrors.WithStackTrace(&corderrors.NoMatchError{})
	} else if len(models) > 1 {
		if !Confirmf("Filter matches %d objects. Continue [y/n] ? ", len(models)) {
			return corderrors.WithStackTrace(&corderrors.AbortedError{})
		}
	}

	fields := make(map[string]interface{})

	if len(options.SetJSON) > 0 {
		fields["_json"] = []byte(options.SetJSON)
	}

	for fieldName, value := range updates {
		value = value[1:]
		proto_value, err := TypeConvert(descriptor, modelName, fieldName, value)
		if err != nil {
			return err
		}
		fields[fieldName] = proto_value
	}

	modelStatusOutput := InitModelStatusOutput(options.Unbuffered, len(models))
	for i, model := range models {
		id := model.GetFieldByName("id").(int32)
		fields["id"] = id
		err := UpdateModel(conn, descriptor, modelName, fields)

		UpdateModelStatusOutput(&modelStatusOutput, i, id, "Updated", err, !options.Sync)
	}

	if options.Sync {
		ctx, cancel := context.WithTimeout(context.Background(), options.SyncTimeout)
		defer cancel()
		for i, model := range models {
			id := model.GetFieldByName("id").(int32)
			if modelStatusOutput.Rows[i].Message == "Updated" {
				conditional_printf(!options.Quiet, "Wait for sync: %d ", id)
				conn, _, err = GetModelWithRetry(ctx, conn, descriptor, modelName, id, GM_UNTIL_ENACTED|Ternary_uint32(options.Quiet, GM_QUIET, 0))
				conditional_printf(!options.Quiet, "\n")
				UpdateModelStatusOutput(&modelStatusOutput, i, id, "Enacted", err, true)
			}
		}
	}

	if !options.Unbuffered {
		FormatAndGenerateOutput(&options.OutputOptions, DEFAULT_UPDATE_FORMAT, DEFAULT_UPDATE_FORMAT, modelStatusOutput.Rows)
	}

	return nil
}

func (options *ModelDelete) Execute(args []string) error {
	conn, descriptor, err := InitClient(INIT_DEFAULT)
	if err != nil {
		return err
	}

	defer conn.Close()

	modelName := string(options.Args.ModelName)
	ids, err := GetIDList(conn, descriptor, modelName, options.IDArgs.ID, options.Filter, options.All)
	if err != nil {
		return err
	}

	modelStatusOutput := InitModelStatusOutput(options.Unbuffered, len(ids))
	for i, id := range ids {
		err = DeleteModel(conn, descriptor, modelName, id)
		UpdateModelStatusOutput(&modelStatusOutput, i, id, "Deleted", err, true)
	}

	if !options.Unbuffered {
		FormatAndGenerateOutput(&options.OutputOptions, DEFAULT_DELETE_FORMAT, DEFAULT_DELETE_FORMAT, modelStatusOutput.Rows)
	}

	return nil
}

func (options *ModelCreate) Execute(args []string) error {
	conn, descriptor, err := InitClient(INIT_DEFAULT)
	if err != nil {
		return err
	}

	defer conn.Close()

	err = CheckModelName(descriptor, string(options.Args.ModelName))
	if err != nil {
		return err
	}

	updates, err := CommaSeparatedQueryToMap(options.SetFields, true)
	if err != nil {
		return err
	}

	modelName := string(options.Args.ModelName)

	fields := make(map[string]interface{})

	if len(options.SetJSON) > 0 {
		fields["_json"] = []byte(options.SetJSON)
	}

	for fieldName, value := range updates {
		value = value[1:]
		proto_value, err := TypeConvert(descriptor, modelName, fieldName, value)
		if err != nil {
			return err
		}
		fields[fieldName] = proto_value
	}

	modelStatusOutput := InitModelStatusOutput(options.Unbuffered, 1)

	err = CreateModel(conn, descriptor, modelName, fields)
	UpdateModelStatusOutput(&modelStatusOutput, 0, fields["id"], "Created", err, !options.Sync)

	if options.Sync {
		ctx, cancel := context.WithTimeout(context.Background(), options.SyncTimeout)
		defer cancel()
		if modelStatusOutput.Rows[0].Message == "Created" {
			id := fields["id"].(int32)
			conditional_printf(!options.Quiet, "Wait for sync: %d ", id)
			conn, _, err = GetModelWithRetry(ctx, conn, descriptor, modelName, id, GM_UNTIL_ENACTED|Ternary_uint32(options.Quiet, GM_QUIET, 0))
			conditional_printf(!options.Quiet, "\n")
			UpdateModelStatusOutput(&modelStatusOutput, 0, id, "Enacted", err, true)
		}
	}

	if !options.Unbuffered {
		FormatAndGenerateOutput(&options.OutputOptions, DEFAULT_CREATE_FORMAT, DEFAULT_CREATE_FORMAT, modelStatusOutput.Rows)
	}

	return nil
}

func (options *ModelSync) Execute(args []string) error {
	conn, descriptor, err := InitClient(INIT_DEFAULT)
	if err != nil {
		return err
	}

	defer conn.Close()

	modelName := string(options.Args.ModelName)
	ids, err := GetIDList(conn, descriptor, modelName, options.IDArgs.ID, options.Filter, options.All)
	if err != nil {
		return err
	}

	ctx, cancel := context.WithTimeout(context.Background(), options.SyncTimeout)
	defer cancel()

	modelStatusOutput := InitModelStatusOutput(options.Unbuffered, len(ids))
	for i, id := range ids {
		conditional_printf(!options.Quiet, "Wait for sync: %d ", id)
		conn, _, err = GetModelWithRetry(ctx, conn, descriptor, modelName, id, GM_UNTIL_ENACTED|Ternary_uint32(options.Quiet, GM_QUIET, 0))
		conditional_printf(!options.Quiet, "\n")
		UpdateModelStatusOutput(&modelStatusOutput, i, id, "Enacted", err, true)
	}

	if !options.Unbuffered {
		FormatAndGenerateOutput(&options.OutputOptions, DEFAULT_SYNC_FORMAT, DEFAULT_SYNC_FORMAT, modelStatusOutput.Rows)
	}

	return nil
}

func (options *ModelSetDirty) Execute(args []string) error {
	conn, descriptor, err := InitClient(INIT_DEFAULT)
	if err != nil {
		return err
	}

	defer conn.Close()

	modelName := string(options.Args.ModelName)
	ids, err := GetIDList(conn, descriptor, modelName, options.IDArgs.ID, options.Filter, options.All)
	if err != nil {
		return err
	}

	modelStatusOutput := InitModelStatusOutput(options.Unbuffered, len(ids))
	for i, id := range ids {
		updateMap := map[string]interface{}{"id": id}
		err := UpdateModel(conn, descriptor, modelName, updateMap)
		UpdateModelStatusOutput(&modelStatusOutput, i, id, "Dirtied", err, true)
	}

	if !options.Unbuffered {
		FormatAndGenerateOutput(&options.OutputOptions, DEFAULT_SYNC_FORMAT, DEFAULT_SYNC_FORMAT, modelStatusOutput.Rows)
	}

	return nil
}

func (modelName *ModelNameString) Complete(match string) []flags.Completion {
	conn, descriptor, err := InitClient(INIT_DEFAULT)
	if err != nil {
		return nil
	}

	defer conn.Close()

	models, err := GetModelNames(descriptor)
	if err != nil {
		return nil
	}

	list := make([]flags.Completion, 0)
	for k := range models {
		if strings.HasPrefix(k, match) {
			list = append(list, flags.Completion{Item: k})
		}
	}

	return list
}
