package dbutil

import (
	"database/sql"
	"fmt"
	"strings"
	errutil "tiloader/pkg/errutil"
	fileutil "tiloader/pkg/fileutil"
	log "tiloader/pkg/logutil"

	"golang.org/x/text/encoding/simplifiedchinese"
)

func GenSql2(rowData string, descFile fileutil.DescFile) (mSqlInfo SqlInfo) {
	//从rowDataCh读取，转换成sql，放到sqlCh

	//组装sql
	//fmt.Println(rowData)

	var str1, str2 string
	// if descFile.Method == fileutil.APPEND {
	// 	str1 = "insert into "
	// } else {
	// 	str1 = "replace into "
	// }
	str1 = "insert into "
	str1 += descFile.TableName
	str1 += "("

	str2 = ""
	str2 += "("
	for i := 0; i < len(descFile.Cols); i++ {
		//fmt.Println("cloname:" + descFile.Cols[i].ColName)
		str1 += descFile.Cols[i].ColName + ","
		value := string(rowData[descFile.Cols[i].PositionStart-1 : descFile.Cols[i].PositionEnd])
		str2 += "'" + value + "',"
	}
	str1 = strings.TrimRight(str1, ",")
	str2 = strings.TrimRight(str2, ",")
	str1 += ")values"
	str2 += ")"
	//sql := str1 + str2 //"insert into test.test_tab(col1, col2, col3) values('a','b','c')"
	//log.WriteLog("str1:" + str1)
	//log.WriteLog("str2:" + str2)
	//log.WriteLog("gen sql:" + sql)

	sqlInfo := SqlInfo{
		SqlHalf1: str1,
		SqlHalf2: str2,
	}

	// log.WriteLog("GenSql() end")

	return sqlInfo
}

type SqlInfo struct {
	SqlHalf1 string
	SqlHalf2 string
	Param    []string
}

func GenSql(rowData string, descFile fileutil.DescFile) (mSqlInfo SqlInfo) {
	//从rowDataCh读取，转换成sql，放到sqlCh

	//组装sql
	//fmt.Println(rowData)

	var str1, str2 string
	str1 = "insert into "
	str1 += descFile.TableName
	str1 += "("

	str2 = ""
	str2 += "("
	for i := 0; i < len(descFile.Cols); i++ {
		//fmt.Println("cloname:" + descFile.Cols[i].ColName)
		str1 += descFile.Cols[i].ColName + ","
		//value := string(rowData[descFile.Cols[i].PositionStart-1 : descFile.Cols[i].PositionEnd-1])
		str2 += "?,"
	}
	str1 = strings.TrimRight(str1, ",")
	str2 = strings.TrimRight(str2, ",")
	str1 += ") values "
	str2 += ")"
	//sql := str1 + str2 //"insert into test.test_tab(col1, col2, col3) values('a','b','c')"
	//log.WriteLog("str1:" + str1)
	//log.WriteLog("str2:" + str2)
	//log.WriteLog("gen sql:" + sql)

	sqlInfo := SqlInfo{
		SqlHalf1: str1,
		SqlHalf2: str2,
	}

	// log.WriteLog("GenSql() end")

	return sqlInfo
}

func GenData(rowData string, descFile fileutil.DescFile, param []string) {
	for i := 0; i < len(descFile.Cols); i++ {
		text := string(rowData[descFile.Cols[i].PositionStart-1 : descFile.Cols[i].PositionEnd])
		if strings.ToUpper(descFile.Charset) == "GBK" {
			byteText := []byte(text)
			utf8Data, _ := simplifiedchinese.GBK.NewDecoder().Bytes(byteText)
			text = string(utf8Data)
		}
		text = strings.TrimRight(text, " ")
		param[i] = text
	}
}

func isGBK(data []byte) bool {
	length := len(data)
	var i int = 0
	for i < length {
		if data[i] <= 0x7f {
			//编码0~127,只有一个字节的编码，兼容ASCII码
			i++
			continue
		} else {
			//大于127的使用双字节编码，落在gbk编码范围内的字符
			if data[i] >= 0x81 &&
				data[i] <= 0xfe &&
				i+1 < length &&
				data[i+1] >= 0x40 &&
				data[i+1] <= 0xfe &&
				data[i+1] != 0xf7 {
				i += 2
				continue
			} else {
				return false
			}
		}
	}
	return true
}

func GenData2(rowData string, descFile fileutil.DescFile, param []string) {
	for i := 0; i < len(descFile.Cols); i++ {
		param[i] = string(rowData[descFile.Cols[i].PositionStart-1 : descFile.Cols[i].PositionEnd])
	}
}

func ExecSql(sql string, params []string, cfg fileutil.ConfigFile) (sql.Result, error) {
	log.WriteLog("Insert() begin")

	db, err := GetDB(cfg)
	if err != nil {
		log.Error("prepare sql failed, err:" + err.Error())
		errutil.ErrCtl()
		return nil, err
	}

	args := make([]interface{}, len(params))

	for i := 0; i < len(params); i++ {
		args[i] = params[i]
	}
	//fmt.Println(sql)
	log.WriteLog(sql)
	result, err := db.Exec(sql, args...)
	if err != nil {
		log.Error("exec failed, err:" + err.Error())
		errutil.ErrCtl()
		return nil, err
	}

	log.WriteLog("Insert() end")
	return result, nil
}

func ExecSql2(sql string, cfg fileutil.ConfigFile) (sql.Result, error) {
	// log.WriteLog("Insert() begin")

	db, err := GetDB(cfg)
	if err != nil {
		fmt.Println(err)
		log.Error("prepare sql failed, err:" + err.Error())
		errutil.ErrCtl()
		return nil, err
	}

	//fmt.Println(sql)
	defer db.Close()
	result, err := db.Exec(sql)
	if err != nil {
		log.Error("exec failed, err:" + err.Error())
		errutil.ErrCtl()
		return nil, err
	}

	// log.WriteLog("Insert() end")
	return result, nil
}
