package main

import (
	"context"
	"encoding/json"
	"flag"
	"fmt"
	"message-service/commons/config"
	"message-service/commons/utils"
	"os"
	"strconv"
	"strings"
	"time"

	service "message-service/internal/service/central"
)

const (
	host                = "http://127.0.0.1:10010"
	defaultConfigPath   = "/etc/dbaas/config.yaml"
	defaulttableSqlPath = "./test/githubevent_auto_evaluation/sample_data/table_info.json"
	defaultOutputPath   = "./test/githubevent_auto_evaluation/sample_data/table_info_with_question.json"
)

var exePath, _ = os.Executable()

type TableInfo struct {
	Database  string   `json:"database"`
	Table     string   `json:"table"`
	Sql       string   `json:"sql"`
	ColName   []string `json:"col_names"`
	Questions []string `json:"questions"`
}

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

	tableInfoContent, _ := utils.ReadFileToString(tableInfoPath)
	var tableInfos []TableInfo
	err = json.Unmarshal([]byte(tableInfoContent), &tableInfos)
	if err != nil {
		panic(fmt.Sprintf("Unmarshal tableInfoContent failed, err: %+v", err))
	}

	for index, tableInfo := range tableInfos {
		questionStr, err := GenQuestionsByCompletionV2(tableInfo.Database, tableInfo.Table, strings.Join(tableInfo.ColName, ", "))
		if err != nil {
			continue
		}
		questionList := strings.Split(questionStr, "\n")
		tableInfos[index].Table = strings.Replace(tableInfos[index].Table, "\n", " ", -1)
		tableInfos[index].Table = strings.Replace(tableInfos[index].Table, "\t", " ", -1)
		tableInfos[index].Questions = []string{}
		for _, question := range questionList {
			if question == "" {
				continue
			}
			tableInfos[index].Questions = append(tableInfos[index].Questions, question)
		}
		time.Sleep(time.Millisecond * 100)
	}
	outputStr, err := json.MarshalIndent(tableInfos, "", "\t")
	utils.WriteStringToFile(outputPath, string(outputStr))
}

func GenQuestionsByCompletion(database, table, columns string) (string, error) {
	ctx := context.Background()
	promptFormat := `### MySQL table
Table %s.%s, columns = [%s]
###
I'm a data analyst
Try to understand this table by table_name and column_name
We want to get some questions for transforming sql
The questions generated should be diverse
Guess the usage of this table
Give me different questions to find interesting data in this table
DO NOT generate questions about "average number"
###
think step by step, guess the usage of this table and generate 30 different questions to find interesting data, all questions are expressed using different sentences`
	// Think step by step, generate 10 questions for this table, do not use repetitive question sentences`
	prompt := fmt.Sprintf(promptFormat, database, table, columns)
	fmt.Println(prompt)
	completion, err := service.CreateCompletionTextDavinci(ctx, prompt)
	if err != nil {
		return "", err
	}
	return completion, nil
}

func GenQuestionsByCompletionV2(database, table, columns string) (string, error) {
	tableLines := []string{}
	splitColumns := strings.Split(columns, ", ")
	splitColumns = formatColumnName(splitColumns)
	line := "Table " + database + "." + table + ", columns = [" + strings.Join(splitColumns, ", ") + "]"
	tableLines = append(tableLines, line)
	template := `#Question Generator for Data Exploring Purpose

` + strings.Join(tableLines, "\n") + `

###Task:
Generate ` + strconv.Itoa(30) + ` interesting questions to explore the data based on the following MySQL database schema:
`
	completion, err := service.CreateCompletionTextDavinci(context.Background(), template)
	if err != nil {
		return "", err
	}
	return completion, nil
}

func formatColumnName(cols []string) []string {
	retList := make([]string, len(cols))
	for index, col := range cols {
		if strings.Contains(col, " ") && !strings.Contains(col, "`") {
			retList[index] = "`" + col + "`"
		} else {
			retList[index] = col
		}
	}
	return retList
}
