package config

import (
	"fmt"
	"io/ioutil"
	"os"

	"github.com/pingcap/enterprise-toolkit/tispector/util/logger"
	"gopkg.in/yaml.v2"
)

const (
	rulePath = "./config/rules.yml"
)

// GetRule Take configuration from the yml file and analysis configuration
// 单元测试时需要填入rules.yml的文件绝对路径
func GetRule(RulePath string) (ruleMap map[string]RuleConf, err error) {
	if RulePath == "" {
		RulePath = rulePath
	}
	_, err = os.Stat(RulePath)
	if err != nil {
		logger.Fatal("Get rule yaml failed; error: %v", err)
		if os.IsNotExist(err) {
			return nil, fmt.Errorf("%s,文件不存在", rulePath)
		}
		return nil, err
	}

	Rulee, err := ioutil.ReadFile(RulePath)
	if err != nil {
		logger.Fatal("Get rule yaml failed; error: %v", err)
		return nil, err
	}
	ruleMap = make(map[string]RuleConf)
	err = yaml.Unmarshal(Rulee, &ruleMap)
	if err != nil {
		logger.Fatal("Get rule yaml failed; error: %v", err)
		return nil, err
	}
	return ruleMap, nil
}

// UodateRule 提供了修改某条规则的方法
func UpdateRule(Rule RuleConf) error {
	ok := 0
	RuleMap, err := GetRule("")
	if err != nil {
		logger.Fatal("GetRule failed ; error: %v", err)
		return err
	}
	for key, value := range RuleMap {
		if value.Item == Rule.Item {
			ok = 1
			if Rule.Name != value.Name || value.Name != "" {
				value.Name = Rule.Name
			}
			if Rule.Summary != value.Summary || value.Summary != "" {
				value.Summary = Rule.Summary
			}
			if Rule.Content != value.Content || value.Content != "" {
				value.Content = Rule.Content
			}

			if Rule.Close != 99 {
				if Rule.Close != value.Close {
					value.Close = Rule.Close
				}
			}
			if Rule.Level != 99 {
				if Rule.Level != value.Level {
					value.Level = Rule.Level
				}
			}
			if Rule.Case != value.Case || value.Case != "" {
				value.Case = Rule.Case
			}
			if Rule.Position != 99 {
				if Rule.Position != value.Position {
					value.Position = Rule.Position
				}
			}
			if Rule.Threshold != value.Threshold || value.Threshold != "" {
				value.Threshold = Rule.Threshold
			}
			RuleMap[key] = value
		}
	}
	if ok == 0 {
		return fmt.Errorf("规则 %s 不存在", Rule.Item)
	}
	if ok == 1 {
		yml, _ := yaml.Marshal(&RuleMap)
		ioutil.WriteFile(`./config/rules.yml`, yml, 0666)
		return nil
	}
	return nil
}

// RuleConf 这个是从yml文件中读取规则的类型
type RuleConf struct {
	// 规则代号
	Item string `yaml:"Item" gorm:"item" json:"Item" `
	// 规则名称
	Name string `yaml:"Name" gorm:"name" json:"Name"`
	// 规则摘要
	Summary string `yaml:"Summary" gorm:"summary" json:"Summary"`
	// 规则解释
	Content string `yaml:"Content" gorm:"content" json:"Content"`
	// 是否禁用
	Close int `yaml:"Close" gorm:"close" json:"Close"`
	// 规则告警等级
	Level int `yaml:"Level" gorm:"level" json:"Level"`
	// SQL示例
	Case string `yaml:"Case" gorm:"case" json:"Case"`
	// 建议所处SQL字符位置，默认0表示全局建议
	Position int `yaml:"Position" gorm:"position" json:"Position"`
	// 函数名
	CheckFunc string `yaml:"CheckFunc" gorm:"checkfunc" json:"CheckFunc"`
	// 阈值
	Threshold string `yaml:"Threshold" gorm:"threshold" json:"Threshold"`
}
