package grmi

import (
	"LAPP_LF_MOM_BACKEND/container"
	"LAPP_LF_MOM_BACKEND/rpc"
	"LAPP_LF_MOM_BACKEND/utils"
	"LAPP_LF_MOM_BACKEND/web/models"
	"errors"
	"fmt"
	"github.com/kataras/iris/v12/core/router"
	"strconv"
	"strings"
	"time"
)

type GoType int

const (
	URLDateTimeFormat = "20060102150405"
	URLDateFormat     = "20060102"
	DateOutFormat     = "2006-01-02"
	DatetimeOutFormat = "2006-01-02 15:04:05"
)

const (
	TypeInt GoType = iota + 1
	TypeInt8
	TypeInt16
	TypeInt32
	TypeInt64
	TypeUint
	TypeUint8
	TypeUint16
	TypeUint32
	TypeUint64
	TypeFloat32
	TypeFloat64
	TypeDate
	TypeDateTime
	TypeBool
	TypeString
)

var componentContainer = container.NewComponentContainer()

var routeManager = rpc.NewRouteManager(componentContainer)

var routeMapping = make(map[string]func(router.Party), 10)

func RegisterRouteMapping(path string, factory func(router.Party)) {
	routeMapping[path] = factory
}

func BindRoutes(party router.Party) {
	for path, factory := range routeMapping {
		party.PartyFunc(path, factory)
	}
	var pathMapping = make(map[string][]string)
	for _, serviceRouteManager := range routeManager.ServiceRouteManagers() {
		serviceRouteManager.BindRoutes(pathMapping, party)
	}
	for path, group := range pathMapping {
		if len(group) > 1 {
			panic(fmt.Sprintf("服务路径冲突! 路径: \"%s\" 服务: %s", path, group))
		}
	}
}

func RepeatStrings(content string, count int) []string {
	result := make([]string, count)
	for index := range result {
		result[index] = content
	}
	return result
}

func Equal(predicate Predicate) (string, error) {
	if predicate.Values == nil || len(predicate.Values) != 1 {
		return "", errors.New("相等性比较只支持一个参数")
	}
	return fmt.Sprintf(" and %s = ?", predicate.ColumnName), nil
}

func NotEqual(predicate Predicate) (string, error) {
	if predicate.Values == nil || len(predicate.Values) != 1 {
		return "", errors.New("相等性比较只支持一个参数")
	}
	return fmt.Sprintf(" and %s <> ?", predicate.ColumnName), nil
}

func Like(predicate Predicate) (string, error) {
	if predicate.Values == nil || len(predicate.Values) != 1 {
		return "", errors.New("相似性比较只支持一个参数")
	}
	return fmt.Sprintf(" and %s like concat('%%', ?, '%%')", predicate.ColumnName), nil
}

func NotLike(predicate Predicate) (string, error) {
	if predicate.Values == nil || len(predicate.Values) != 1 {
		return "", errors.New("相似性比较只支持一个参数")
	}
	return fmt.Sprintf(" and %s not like concat('%%', ?, '%%')", predicate.ColumnName), nil
}

func IsNull(predicate Predicate) (string, error) {
	if predicate.Values != nil && len(predicate.Values) > 0 {
		return "", errors.New("为空比较比较不支持参数")
	}
	return fmt.Sprintf(" and %s is null", predicate.ColumnName), nil
}

func IsNotNull(predicate Predicate) (string, error) {
	if predicate.Values != nil && len(predicate.Values) > 0 {
		return "", errors.New("为空比较比较不支持参数")
	}
	return fmt.Sprintf(" and %s is not null", predicate.ColumnName), nil
}

func Include(predicate Predicate) (string, error) {
	if predicate.Values != nil && len(predicate.Values) > 0 {
		return fmt.Sprintf(" and %s in (%s)", predicate.ColumnName, strings.Join(RepeatStrings("?", len(predicate.Values)), ",")), nil
	} else {
		return " and 1 <> 1", nil
	}
}

func Exclude(predicate Predicate) (string, error) {
	if predicate.Values != nil && len(predicate.Values) > 0 {
		return fmt.Sprintf(" and %s not in (%s)", predicate.ColumnName, strings.Join(RepeatStrings("?", len(predicate.Values)), ",")), nil
	} else {
		return " and 1 = 1", nil
	}
}

func Approximate(predicate Predicate) (string, error) {
	if predicate.Values == nil || len(predicate.Values) != 1 {
		return "", errors.New("约等于比较比较只支持一个参数")
	}
	return fmt.Sprintf(" and datediff(second, %s, ?) = 0", predicate.ColumnName), nil
}

func NotApproximate(predicate Predicate) (string, error) {
	if predicate.Values == nil || len(predicate.Values) != 1 {
		return "", errors.New("约等于比较比较只支持一个参数")
	}
	return fmt.Sprintf(" and datediff(second, %s, ?) <> 0", predicate.ColumnName), nil
}

func GreaterThen(predicate Predicate) (string, error) {
	if predicate.Values == nil || len(predicate.Values) != 1 {
		return "", errors.New("大于比较比较只支持一个参数")
	}
	return fmt.Sprintf(" and %s > ?", predicate.ColumnName), nil
}

func GreaterOrEqual(predicate Predicate) (string, error) {
	if predicate.Values == nil || len(predicate.Values) != 1 {
		return "", errors.New("大于等于比较比较只支持一个参数")
	}
	return fmt.Sprintf(" and %s >= ?", predicate.ColumnName), nil
}

func LessThen(predicate Predicate) (string, error) {
	if predicate.Values == nil || len(predicate.Values) != 1 {
		return "", errors.New("小于比较比较只支持一个参数")
	}
	return fmt.Sprintf(" and %s < ?", predicate.ColumnName), nil
}

func LessOrEqual(predicate Predicate) (string, error) {
	if predicate.Values == nil || len(predicate.Values) != 1 {
		return "", errors.New("小于等于比较比较只支持一个参数")
	}
	return fmt.Sprintf(" and %s <= ?", predicate.ColumnName), nil
}

func Log(user *models.Usertab, codeFile string, function string, message string) {

	logs := new(models.LeitServerLog)
	logs.File = codeFile
	logs.Level = "info"
	logs.Function = function
	logs.Message = message
	logs.Operator = user.Userid
	logs.TimeStamp = utils.TimeFormat(time.Now(), "yyyyMMddHHmmss")
	logs.InsertRecord()
}

func intParser(value string) (interface{}, error) {
	predicateValue, err := strconv.ParseInt(value, 10, 64)
	if err != nil {
		return nil, err
	}
	return predicateValue, nil
}

func uint64Parser(value string) (interface{}, error) {
	predicateValue, err := strconv.ParseUint(value, 10, 64)
	if err != nil {
		return nil, err
	}
	return predicateValue, nil
}

func floatParser(value string) (interface{}, error) {
	predicateValue, err := strconv.ParseFloat(value, 64)
	if err != nil {
		return nil, err
	}
	return predicateValue, nil
}

func dateTimeParser(value string) (interface{}, error) {
	predicateValue, err := time.Parse(URLDateTimeFormat, value)
	if err != nil {
		return nil, err
	}
	return predicateValue, nil
}

func dateParser(value string) (interface{}, error) {
	predicateValue, err := time.Parse(URLDateFormat, value)
	if err != nil {
		return nil, err
	}
	return predicateValue, nil
}

func boolParser(value string) (interface{}, error) {
	predicateValue, err := strconv.ParseBool(value)
	if err != nil {
		return nil, err
	}
	return predicateValue, nil
}

func stringParser(value string) (interface{}, error) {
	return strings.TrimSpace(value), nil
}

var valueParsers = map[GoType]func(string) (interface{}, error){
	TypeInt:      intParser,
	TypeInt8:     intParser,
	TypeInt16:    intParser,
	TypeInt32:    intParser,
	TypeInt64:    intParser,
	TypeUint:     intParser,
	TypeUint8:    intParser,
	TypeUint16:   intParser,
	TypeUint32:   intParser,
	TypeUint64:   uint64Parser,
	TypeFloat32:  floatParser,
	TypeFloat64:  floatParser,
	TypeDateTime: dateTimeParser,
	TypeDate:     dateParser,
	TypeBool:     boolParser,
	TypeString:   stringParser,
}

/******************************************************************************
 *
 * @Function Name            : DeleteUrlParametersEmpty
 *-----------------------------------------------------------------------------
 *
 * @Description              : 删除urlParameters的空字符串
 *
 * @Function Parameters      : 删除urlParameters的空字符串
 *
 * @Author                   : 张鑫
 *
 * @Date                     : 2021-03-24
 *
 ******************************************************************************/
func DeleteUrlParametersEmpty(urlParameters *map[string]string) {
	for key, value := range *urlParameters {
		if value == "" {
			delete(*urlParameters, key)
		}
	}
}
