package main

import (
	"bufio"
	"context"
	"flag"
	"fmt"
	"io"
	"message-service/commons/config"
	"message-service/commons/httpclient"
	"message-service/internal/bean/dto"
	service_central "message-service/internal/service/central"
	"os"
	"path/filepath"
	"strconv"
	"strings"

	"github.com/pingcap/log"
	"github.com/tidbcloud/tiinf/errs"
	"go.uber.org/zap"
	"k8s.io/apimachinery/pkg/util/json"
)

const (
	host              = "http://127.0.0.1:10010"
	defaultConfigPath = "/etc/dbaas/config.yaml"
)

var exePath, _ = os.Executable()
var questionFile = filepath.Dir(exePath) + "/../test/chatgpt/questionFile.list"
var answerFile_GithubEvent = filepath.Dir(exePath) + "/../test/chatgpt/answerFile_text-davinci-003.txt"
var answerFile_GithubEventCode = filepath.Dir(exePath) + "/../test/chatgpt/answerFile_code-davinci-002.txt"
var answerFile_SqlEditorNoDatabase = filepath.Dir(exePath) + "/../test/chatgpt/answerFile_sqleditor_no_database.txt"

type Data struct {
	Code    int         `json:"code"`
	Message string      `json:"message"`
	Data    interface{} `json:"data"`
}

func WriteStringToFile(fileName string, content string) error {
	file, err := os.OpenFile(fileName, os.O_WRONLY|os.O_CREATE, 0666)
	if err != nil {
		fmt.Println("OpenFile failed", err)
		return err
	}
	defer file.Close()
	write := bufio.NewWriter(file)
	write.WriteString(content)
	write.Flush()
	return nil
}
func ReadFileToList(fileName string) (*[]string, error) {
	fi, err := os.Open(fileName)
	if err != nil {
		fmt.Printf("Error: %s\n", err)
		return nil, errs.NewBadRequest("no file found : "+fileName, nil)
	}
	defer fi.Close()

	var resList []string
	br := bufio.NewReader(fi)
	for {
		a, _, c := br.ReadLine()
		if c == io.EOF {
			break
		}
		resList = append(resList, string(a))
	}
	return &resList, nil
}

func main() {
	var configPath string
	flag.StringVar(&configPath, "config-path", defaultConfigPath, "DBaaS configuration file path")
	flag.Parse()
	err := config.InitConfig(configPath)
	if err != nil {
		panic(fmt.Sprintf("Initialize configuration failed, err: %+v", err))
	}

	questionList, err := ReadFileToList(questionFile)
	if err != nil {
		panic("ReadFileToList failed.")
		return
	}
	testCompletionSqlEditorNoDatabase(questionList, answerFile_SqlEditorNoDatabase)
}

func testCompletionSqlEditorNoDatabase(questionList *[]string, outputFile string) {
	ctx := context.Background()
	searchRecords := ""
	rawSqlRecords := ""
	for index, question := range *questionList {
		//	time.Sleep(7 * time.Second)
		record := "++++++++++++++++++++++++++++\n"
		record += "[" + strconv.Itoa(index) + "] Q: " + question + "\n"
		req := &dto.InteractRequest{
			BotType:   "sqleditor_no_database",
			Question:  question,
			ProjectID: 43563,
			ClusterID: "120790",
		}
		finalprompt, res, _ := service_central.CreateCompletionWithReq(ctx, req)
		log.Info(finalprompt)
		record += "A: " + res + "\n"
		log.Info(record)
		searchRecords += record
		rawSqlRecords += strings.Replace(res, "\n", " ", -1) + ";\n"
	}
	WriteStringToFile(outputFile, searchRecords)
	WriteStringToFile(outputFile+"_RAW", rawSqlRecords)
}

func testCompletion(questionList *[]string, tpl string, outputFile string) {
	ctx := context.Background()
	searchRecords := ""
	rawSqlRecords := ""
	for index, question := range *questionList {
		//	time.Sleep(7 * time.Second)
		record := "++++++++++++++++++++++++++++\n"
		record += "[" + strconv.Itoa(index) + "] Q: " + question + "\n"
		finalprompt, res, _ := service_central.CreateCompletionWithTemplate(ctx, question, tpl)
		log.Info(finalprompt)
		record += "A: " + res + "\n"
		log.Info(record)
		searchRecords += record
		rawSqlRecords += strings.Replace(res, "\n", " ", -1) + ";\n"
	}
	WriteStringToFile(outputFile, searchRecords)
	WriteStringToFile(outputFile+"_RAW", rawSqlRecords)
}

func testCompletionInProd(question string) (string, error) {
	orgId := 1372813089202881281
	projectId := 1372813089200961282
	prodToken := "Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IlJEWTNNVUpGTUVReU9VVTBSa0U1TXpCRk5rRkRRVEl3UkRNMU0wSXpNelJHUVRrMVFUbEZRZyJ9.eyJodHRwczovL3RpZGJjbG91ZC5jb20vbG9naW5fcmVjZWl2ZWRfYXQiOjE2NzIxNDQ0Mjc4MjEsImVtYWlsIjoiYmluZy53YW5nQHBpbmdjYXAuY29tIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsImlzcyI6Imh0dHBzOi8vdGlkYi5hdXRoMC5jb20vIiwic3ViIjoiZ29vZ2xlLW9hdXRoMnwxMDQyODU4NDkzNDgwODMwNjQ2ODAiLCJhdWQiOiI2SVp0aENmbVJLSVBFblFTVDhhRGJ0TTdTR2RNbmlSbCIsImlhdCI6MTY3MjE0NDQyNywiZXhwIjoxNjcyMTgwNDI3LCJhdF9oYXNoIjoiZmpfUDhNYk9pU1B6MlQ3Nl85d25DQSIsInNpZCI6ImxvbnVieXlhQkFrQWZCZEV0VmtEX3l1X0FZN3d2Rk1rIiwibm9uY2UiOiJtZHBGUmZRU2xJY0ExWGt2Uk1oQk5EYzI5TGYyRjJlMiJ9.oczdD9E6tK_ziPoYiHdMTufOqoT7wHe34t2L_Cw7CjGDCAQ41hcY_rcoy5G1po_XvHb2yEWEsJN0PP7YRNfPIQs2V2CKup2wQZBfpLevo0sCStgrWExY077CgGoz_To3N67uWHM9JW6jX34T8kky1gerq6t5fp2omIK5_hAJquLXZfovIc2cUKuLS5ORZ8QhsONjQV4E_B2Bw_QyCh69Tam1twPym84RMOOhtmiGfKGjV5xjhnb5Rm1swUvWciSHEdTfBr4MEDrgF_P-XsSC__7DXwgxvFdDFwNJ426PijuCzCpVq9OVuj_OTS36tABIhekfzqkriHmKF_hj-_umXA"
	prodhost := "https://us-west-2.prod.aws.tidbcloud.com"
	return testInteractBot(prodhost, prodToken, orgId, projectId, question)
}

func testInteractBot(localhost string, token string, orgId int, projectId int, question string) (string, error) {
	header := map[string]string{"test-email": token, "authorization": token}
	url := localhost + "/api/v1/message/orgs/" + strconv.Itoa(orgId) + "/projects/" + strconv.Itoa(projectId) + "/bot"
	params := map[string]string{"question": question, "bot_type": "githubevents"}
	resp, code, err := httpclient.PostWithHeader(url, params, &header)
	if err != nil {
		log.Error("fail to get response ", zap.Error(err))
	}
	var respObj dto.InteractResponse
	err = json.Unmarshal([]byte(resp), &respObj)
	if err != nil {
		return "", err
	}
	log.Info("resp code is  " + strconv.Itoa(code) + " body is " + respObj.Response)
	return respObj.Response, nil
}
