package main

import (
	"bufio"
	"context"
	"fmt"
	"log"
	"os"
	"regexp"
	"unicode"

	"golang.org/x/text/encoding/simplifiedchinese"
	"golang.org/x/text/language"
	"golang.org/x/text/transform"

	"cloud.google.com/go/translate"
	"google.golang.org/api/option"
)

const dbcReadFilePath = "../orig/121-N60AB_ADASBUS_Matrix_CANFD_V2.3.dbc"
const dbcWriteFilePath = "../dbc/n60.dbc"
const googleAPIProjectKey = ""

var enc = simplifiedchinese.GB18030
var lexicon map[string]string

func main() {
	lexicon = make(map[string]string)
	reg, err := regexp.Compile("[^a-zA-Z0-9]+")
	if err != nil {
		log.Fatal(err)
	}

	readFile, err := os.Open(dbcReadFilePath)
	if err != nil {
		log.Fatal(err)
	}
	defer readFile.Close()
	r := transform.NewReader(readFile, enc.NewDecoder())

	writeFile, err := os.Create(dbcWriteFilePath)
	defer writeFile.Close()
	w := transform.NewWriter(writeFile, enc.NewEncoder())

	scanner := bufio.NewScanner(r)
	for scanner.Scan() {
		line := scanner.Text()
		indices := findIndices(line, "\"")
		newline := ""

		if len(indices) == 0 {
			newline = line
		} else {
			for i := 0; i < len(indices); i += 2 {
				if i-1 >= 0 {
					newline += line[indices[i-1]+1 : indices[i]]
				} else {
					newline += line[:indices[i]]
				}

				newline += "\""
				value := line[indices[i]+1 : indices[i+1]]

				fmt.Println(value, containsChinese(value))
				if containsChinese(value) {
					translatedValue, err := translateText(value)
					if err != nil {
						log.Fatal(err)
					}
					fmt.Println(translatedValue)
					value = translatedValue
				}

				newline += reg.ReplaceAllString(value, "")
				newline += "\""
			}

			newline += line[indices[len(indices)-1]+1:]
		}

		fmt.Fprintln(w, newline)
	}

	fmt.Printf("strings translated: %v", len(lexicon))
}

func findIndices(text string, char string) []int {
	var indices []int

	for i, c := range text {
		if string(c) == char {
			indices = append(indices, i)
		}
	}

	if len(indices)%2 != 0 {
		return make([]int, 0)
	}

	return indices
}

func containsChinese(text string) bool {
	for _, runeValue := range text {
		if unicode.Is(unicode.Han, runeValue) {
			return true
		}
	}
	return false
}

func translateText(text string) (string, error) {
	if translated, ok := lexicon[text]; ok {
		return translated, nil
	}

	ctx := context.Background()

	client, err := translate.NewClient(ctx, option.WithAPIKey(googleAPIProjectKey))
	if err != nil {
		return "", err
	}
	defer client.Close()

	resp, err := client.Translate(ctx, []string{text}, language.English, nil)
	if err != nil {
		return "", fmt.Errorf("Translate: %v", err)
	}
	if len(resp) == 0 {
		return "", fmt.Errorf("Translate returned empty response to text: %s", text)
	}

	lexicon[text] = resp[0].Text

	return resp[0].Text, nil
}
