package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
	"strconv"
	"time"
)

// ClientMenu 客户端菜单
type ClientMenu struct {
	Code     string       `json:"code"`     // ID
	Title    string       `json:"title"`    // 标题
	Sort     int          `json:"sort"`     // 排序
	Type     int          `json:"type"`     // 类型，1：菜单 2：按钮
	RuleKey  string       `json:"rulekey"`  // 对应权限主键，对应FUNCMENULIST表RESOURCECODE
	IsShow   bool         `json:"isshow"`   // 是否显示
	URL      string       `json:"url"`      // URL
	Remark   string       `json:"remark"`   // 备注
	Children []ClientMenu `json:"children"` // 子菜单列表
}

// 主要用于风管云平台，将以PC菜单json文件来生成权限SQL权限脚本
func main() {
	var (
		jsonFile   string // JSON文件地址
		clientType string // 终端类型: 1-PCWEB 2-手机
	)

	fmt.Println("请输入终端类型: (3-手机 4-PC大宗 5-PC风管)")
	fmt.Scanln(&clientType)

	fmt.Println("请输入菜单JSON文件地址:")
	fmt.Scanln(&jsonFile)
	fmt.Println("正在处理，请稍等……")

	// 读取Json文件
	filePtr, err := os.Open(jsonFile)
	if err != nil {
		// 读取文件失败
		defer filePtr.Close()
		fmt.Printf("文件读取失败，错误：%s", err.Error())
		return
	}
	defer filePtr.Close()

	// 创建Json编码器
	var datas []interface{}
	decoder := json.NewDecoder(filePtr)
	if err = decoder.Decode(&datas); err != nil {
		// Json解码失败
		fmt.Printf("Json解码失败，错误：%s", err.Error())
		return
	}

	s := "-- 权限控制\n"
	if clientType == "4" {
		s += "-- 说明：MENUTYPE = 4 为PC大宗专用的终端权限\n"
		s += "DELETE FROM FUNCMENULIST WHERE MENUTYPE=4;\n\n"
	} else if clientType == "5" {
		s += "-- 说明：MENUTYPE = 5 为PC风管专用的终端权限\n"
		s += "DELETE FROM FUNCMENULIST WHERE MENUTYPE=5;\n\n"
	} else if clientType == "3" {
		s += "-- 说明：MENUTYPE = 3 为手机专用的终端权限\n"
		s += "DELETE FROM FUNCMENULIST WHERE MENUTYPE=3;\n\n"
	} else {
		fmt.Printf("错误的终端类型。")
		return
	}

	t, _ := strconv.Atoi(clientType)
	if clientType == "4" || clientType == "5" {
		s += buildPCWEBSQL(datas, "", 1, t)
	} else {
		s += buildSQL(datas, "", 1)
	}

	// 判断out文件夹是否存在
	isExists, err := PathExists("out")
	if !isExists || err != nil {
		os.Mkdir("out", os.ModePerm)
	}

	// 写入SQL文件
	outFile := fmt.Sprintf("out/%s%s", time.Now().Format("20060102150405"), ".sql")
	if ioutil.WriteFile(outFile, []byte(s), 0644) == nil {
		fmt.Printf("写入文件成功: %s\n", outFile)
	}
}

func PathExists(path string) (bool, error) {
	_, err := os.Stat(path)
	if err == nil {
		return true, nil
	}
	if os.IsNotExist(err) {
		return false, nil
	}
	return false, err
}

// buildSQL 构建手机SQL
func buildSQL(datas []interface{}, parentCode string, level int) string {
	var sql string

	for i, v := range datas {
		data := v.(map[string]interface{})
		var (
			remark string
		)

		rulekey, hasRuleKey := data["rulekey"]
		if hasRuleKey && rulekey != "" {
			rulekey = data["rulekey"].(string)

			if data["remark"] != nil {
				remark = data["remark"].(string)
			}

			sql += "INSERT INTO FUNCMENULIST (RESOURCECODE, RESOURCENAME, RESOURCELEVEL, MENUTYPE, PARENTCODE, URL, SORT, ICONAME, REMARK)\n"
			if parentCode == "" {
				sql += fmt.Sprintf("VALUES('%s', '%s', %d, 3, NULL, '', %d, '', '%s');\n", rulekey, data["title"].(string), level, i+1, remark)
			} else {
				sql += fmt.Sprintf("VALUES('%s', '%s', %d, 3, '%s', '', %d, '', '%s');\n", rulekey, data["title"].(string), level, parentCode, i+1, remark)
			}

			// 递归
			sub := data["children"].([]interface{})
			if len(sub) > 0 {
				sql += buildSQL(data["children"].([]interface{}), data["rulekey"].(string), level+1)
			}

			if level == 1 {
				sql += "\n"
			}
		}
	}

	return sql
}

// 构建PC WEB SQL
func buildPCWEBSQL(datas []interface{}, parentCode string, level int, clientType int) string {
	var sql string

	for i, v := range datas {
		data := v.(map[string]interface{})
		var (
			remark string
		)

		rulekey, hasRuleKey := data["rulekey"]
		if hasRuleKey && rulekey != "" {
			rulekey = data["rulekey"].(string)

			if data["remark"] != nil {
				remark = data["remark"].(string)
			}

			title := ""
			if data["title"] != nil {
				title = data["title"].(string)
			} else {
				title = data["label"].(string)
			}

			sql += "INSERT INTO FUNCMENULIST (RESOURCECODE, RESOURCENAME, RESOURCELEVEL, MENUTYPE, PARENTCODE, URL, SORT, ICONAME, REMARK)\n"
			if parentCode == "" {
				sql += fmt.Sprintf("VALUES('%s', '%s', %d, %d, NULL, '', %d, '', '%s');\n", rulekey, title, level, clientType, i+1, remark)
			} else {
				sql += fmt.Sprintf("VALUES('%s', '%s', %d, %d, '%s', '', %d, '', '%s');\n", rulekey, title, level, clientType, parentCode, i+1, remark)
			}

			// 递归
			if data["auth"] != nil {
				sql += buildPCWEBSQL(data["auth"].([]interface{}), data["rulekey"].(string), level+1, clientType)
			}
			if data["children"] != nil {
				sql += buildPCWEBSQL(data["children"].([]interface{}), data["rulekey"].(string), level+1, clientType)
			}

			if level == 1 {
				sql += "\n"
			}
		}
	}

	return sql
}
