// score
package extract

import (
	"fmt"
	ju "jy/util"
	"log"
	qu "qfw/util"
	"regexp"
	"strings"
)

var SoreConfig map[string]map[string]interface{}

func init() {
	qu.ReadConfig("./res/fieldscore.json", &SoreConfig)
	//实例化正则
	for _, tmp := range SoreConfig {
		if tmp["type"] == "string" {
			if positions, ok := tmp["position"].([]interface{}); ok {
				for _, position := range positions {
					if p, ok := position.(map[string]interface{}); ok {
						qu.Try(func() {
							p["regexp"] = regexp.MustCompile(qu.ObjToString(p["regstr"]))
						}, func(err interface{}) {
							log.Println(err)
						})
					}
				}
			}
		}
	}
}

//结果打分
func ScoreFields(j *ju.Job) map[string][]*ju.ExtField {
	result := j.Result
	if len(j.Winnerorder) > 0 { //候选人加入打分集合
		winner := &ju.ExtField{
			Field:     "winner",
			Code:      "",
			RuleText:  "",
			Type:      "winnerorder",
			MatchType: "winnerorder",
			ExtFrom:   "",
			Value:     j.Winnerorder[0]["entname"],
			Score:     0,
		}
		if len([]rune(qu.ObjToString(j.Winnerorder[0]["entname"]))) < 4 {
			winner.Score = -5
		}
		winners := result["winner"]
		if winners != nil {
			winners = append(winners, winner)
		} else {
			winners = []*ju.ExtField{}
			winners = append(winners, winner)
		}
		result["winner"] = winners
	}
	//打分
	for field, tmps := range result {
		scoreRule := SoreConfig[field]
		if scoreRule == nil {
			continue
		}
		extractype := SoreConfig["extractype"]
		fieldtype := scoreRule["type"]
		for _, v := range tmps {
			if len(fmt.Sprint(v.Value)) < 1 {
				continue //空串跳过
			}
			//长度超过100个字，直接负分
			vlen := len([]rune(qu.ObjToString(v.Value)))
			if vlen > 100 && field != "projectscope" {
				v.Score = -1
			} else {
				//类型打分
				if v.ExtFrom == "title" {
					v.Score += qu.IntAll(extractype["title"])
				} else {
					if strings.Contains(v.Type, "table") {
						v.Score += qu.IntAll(extractype["table"])
					} else if strings.Contains(v.Type, "colon") {
						v.Score += qu.IntAll(extractype["colon"])
					} else if strings.Contains(v.Type, "space") {
						v.Score += qu.IntAll(extractype["space"])
					} else if strings.Contains(v.Type, "regexp") {
						v.Score += qu.IntAll(extractype["regexp"])
					} else if strings.Contains(v.Type, "winnerorder") {
						v.Score += qu.IntAll(extractype["winnerorder"])
					}
				}
				//字符型打分
				if fieldtype == "string" {
					//位置打分
					if positions, ok := scoreRule["position"].([]interface{}); ok {
						for _, position := range positions {
							if p, ok := position.(map[string]interface{}); ok {
								qu.Try(func() {
									if p["regexp"] != nil {
										reg := p["regexp"].(*regexp.Regexp)
										if reg.MatchString(qu.ObjToString(v.Value)) {
											v.Score += qu.IntAll(p["score"])
										}
									}
								}, func(err interface{}) {
									log.Println(err)
								})
							}
						}
					}
					//长度打分
					if lengths, ok := scoreRule["length"].([]interface{}); ok {
						for _, tmp := range lengths {
							if length, ok := tmp.(map[string]interface{}); ok {
								min := qu.IntAll(length["min"])
								max := qu.IntAll(length["max"])
								scores, _ := length["score"].([]interface{})
								if len(scores) < 3 {
									continue
								}
								if vlen < min {
									v.Score += qu.IntAll(scores[0])
								} else if vlen > max {
									v.Score += qu.IntAll(scores[2])
								} else {
									v.Score += qu.IntAll(scores[1])
								}
							}
						}
					}
				}
				//float类型打分
				if fieldtype == "float" {
					min := qu.IntAll(scoreRule["min"])
					max := qu.IntAll(scoreRule["max"])
					val := qu.IntAll(v.Value)
					scores, _ := scoreRule["score"].([]interface{})
					if len(scores) < 3 {
						continue
					}
					if val < min && 0 < val {
						v.Score += qu.IntAll(scores[0])
					} else if val > max {
						v.Score += qu.IntAll(scores[2])
					} else if val <= max && val >= min {
						v.Score += qu.IntAll(scores[1])
					}
				}
				//decimal
				if fieldtype == "decimal" {
					min := qu.IntAll(scoreRule["min"])
					max := qu.IntAll(scoreRule["max"])
					val := qu.IntAll(v.Value)
					scores, _ := scoreRule["score"].([]interface{})
					if len(scores) < 3 {
						continue
					}
					if val > max {
						v.Score += qu.IntAll(scores[2])
					} else if val <= max && val > min {
						v.Score += qu.IntAll(scores[1])
					}
				}
			}
		}
	}
	return result
}
