package tools

import (
	"encoding/csv"
	"encoding/json"
	"fmt"
	"io"
	"os"
	"strings"
)

type DiffClusters struct {
	ClusterA ClusterMeta `json:"clusterA"`
	ClusterB ClusterMeta `json:"clusterB"`
}

type ClusterMeta struct {
	Alias string `json:"alias"`
}

type DiffInfo struct {
	Key      string  `json:"key"`
	ClusterA float64 `json:"clusterA"`
	ClusterB float64 `json:"clusterB"`
	Diff     float64 `json:"diff"`
}

type DigestDiff struct {
	Digest    string     `json:"digest"`
	Label     string     `json:"label"`
	SQL       string     `json:"sql"`
	DiffInfos []DiffInfo `json:"diffInfos"`
}

type TopSqlTidbDigestDiff struct {
	DigestDiff []DigestDiff `json:"digestDiff"`
}

type Root struct {
	DiffClusters         DiffClusters         `json:"diffClusters"`
	TopSqlTidbDigestDiff TopSqlTidbDigestDiff `json:"topSqlTidbDigestDiff"`
}

type CsvRow struct {
	ClusterAAlias             string
	ClusterBAlias             string
	Digest                    string
	ClusterATopSqlCount       float64
	ClusterBTopSqlCount       float64
	ClusterATopSqlTidbCPUTime float64
	ClusterBTopSqlTidbCPUTime float64
	ClusterATopSqlTiKVCpuTime float64
	ClusterBTopSqlTiKVCpuTime float64
	ClusterATopSqlAvgLatency  float64
	ClusterBTopSqlAvgLatency  float64
	SQL                       string
}

// readJSONFile 读取并解析 JSON 文件
func readJSONFile(filename string) (*Root, error) {
	data, err := os.ReadFile(filename)
	if err != nil {
		return nil, fmt.Errorf("无法读取文件 %s: %w", filename, err)
	}

	var root Root
	if err := json.Unmarshal(data, &root); err != nil {
		return nil, fmt.Errorf("解析 JSON 文件失败: %w", err)
	}

	return &root, nil
}

// processData  to csv
func processData(root *Root) [][]string {
	var csvData [][]string
	header := []string{
		"clusterA", "clusterB", "digest",
		"clusterA_topsql_count", "clusterB_topsql_count",
		"clusterA_topsql_tidb_cpu_time", "clusterB_topsql_tidb_cpu_time",
		"clusterA_topsql_tikv_cpu_time", "clusterB_topsql_tikv_cpu_time",
		"clusterA_topsql_avg_latency", "clusterB_topsql_avg_latency",
		"sql",
	}
	csvData = append(csvData, header)

	aliasA := root.DiffClusters.ClusterA.Alias
	aliasB := root.DiffClusters.ClusterB.Alias

	for _, diff := range root.TopSqlTidbDigestDiff.DigestDiff {
		row := CsvRow{
			ClusterAAlias: aliasA,
			ClusterBAlias: aliasB,
			Digest:        diff.Digest,
			SQL:           diff.SQL,
		}

		for _, info := range diff.DiffInfos {
			switch info.Key {
			case "topsql_count":
				row.ClusterATopSqlCount = info.ClusterA
				row.ClusterBTopSqlCount = info.ClusterB
			case "topsql_tidb_cpu_time":
				row.ClusterATopSqlTidbCPUTime = info.ClusterA
				row.ClusterBTopSqlTidbCPUTime = info.ClusterB
			case "topsql_tikv_cpu_time":
				row.ClusterATopSqlTiKVCpuTime = info.ClusterA
				row.ClusterBTopSqlTiKVCpuTime = info.ClusterB
			case "topsql_avg_latency":
				row.ClusterATopSqlAvgLatency = info.ClusterA
				row.ClusterBTopSqlAvgLatency = info.ClusterB
			}
		}

		csvRow := []string{
			row.ClusterAAlias,
			row.ClusterBAlias,
			row.Digest,
			fmt.Sprintf("%.0f", row.ClusterATopSqlCount),
			fmt.Sprintf("%.0f", row.ClusterBTopSqlCount),
			fmt.Sprintf("%.2f", row.ClusterATopSqlTidbCPUTime),
			fmt.Sprintf("%.2f", row.ClusterBTopSqlTidbCPUTime),
			fmt.Sprintf("%.2f", row.ClusterATopSqlTiKVCpuTime),
			fmt.Sprintf("%.2f", row.ClusterBTopSqlTiKVCpuTime),
			fmt.Sprintf("%.2f", row.ClusterATopSqlAvgLatency),
			fmt.Sprintf("%.2f", row.ClusterBTopSqlAvgLatency),
			strings.ReplaceAll(row.SQL, "\n", " "),
		}
		csvData = append(csvData, csvRow)
	}
	return csvData
}

// writeCSV 将数据写入 io.Writer (例如 os.Stdout)
func writeCSV(w io.Writer, data [][]string) error {
	writer := csv.NewWriter(w)
	writer.Comma = ','

	err := writer.WriteAll(data)
	if err != nil {
		return err
	}

	writer.Flush()
	return writer.Error()
}



func main() {
	// 检查命令行参数
	if len(os.Args) < 2 {
		fmt.Println("用法: go run parser.go <json文件路径>")
		// 或者直接编译运行: ./parser <json文件路径>
		os.Exit(1)
	}

	filename := os.Args[1] // 第一个参数是文件名

	// 1. 读取并解析 JSON 文件
	root, err := readJSONFile(filename)
	if err != nil {
		fmt.Println("错误:", err)
		os.Exit(1)
	}

	// 2. 处理数据生成 CSV 结构
	csvData := processData(root)

	// 3. 写入 CSV 到标准输出
	err = writeCSV(os.Stdout, csvData)
	if err != nil {
		fmt.Println("写入 CSV 错误:", err)
		os.Exit(1)
	}
}
func ParseToCsv(jsonFilePath string, csvFilePath string) {
	// // 检查命令行参数
	// if len(os.Args) < 2 {
	// 	fmt.Println("用法: go run parser.go <json文件路径>")
	// 	// 或者直接编译运行: ./parser <json文件路径>
	// 	os.Exit(1)
	// }

	// filename := os.Args[1] // 第一个参数是文件名

	// 1. 读取并解析 JSON 文件
	root, err := readJSONFile(jsonFilePath)
	if err != nil {
		fmt.Println("错误:", err)
		os.Exit(1)
	}

	// 2. 处理数据生成 CSV 结构
	csvData := processData(root)

	// 3. 写入 CSV 到标准输出
	err = writeCSV(os.Stdout, csvData)
	if err != nil {
		fmt.Println("写入 CSV 错误:", err)
		os.Exit(1)
	}
}
