package main
import (
	"audio_to_text/store"
	"bytes"
	"fmt"
	"io"
	"log"
	"log/slog"
	"net/http"
	"os"
	"os/exec"
	"strings"
	"sync"
)
var (
	xlog = slog.New(slog.NewTextHandler(os.Stdout, nil))
)
func main() {
	input, err := store.Store.Get("INPUT")
	if err != nil {
		xlog.Error("failed to get input from kv store", "error", err)
		return
	}
	source := input["source_url"].(string)
	if strings.EqualFold(source, "") {
		xlog.Error("not found 'source_url'", source)
	}
	model := input["model"].(string)
	if strings.EqualFold(source, "") {
		xlog.Error("not found 'source_url'", source)
	}
	transcription(source, model)
}
func Test() {
	url := "https://raw.githubusercontent.com/donjuanMime/audio_to_text/main/video.mp4"
	model := "tiny"
	transcription(url, model)
}
func transcription(sourceUrl, model string) {
	downloadFile(sourceUrl)
	filename := "video.mp4"
	command := fmt.Sprintf(`whisper-ctranslate2 %s --batched true --batch_size 4 --max_words_per_line 8 --word_timestamps true --vad_filter true --model %s`, filename, model)
	runCmdWithProgress(command)
}
func runCmdWithProgress(command string) bool {
	cmd := exec.Command("bash", "-c", command)
	var stdoutBuf, stderrBuf bytes.Buffer
	stdoutIn, _ := cmd.StdoutPipe()
	stderrIn, _ := cmd.StderrPipe()
	var errStdout, errStderr error
	stdout := io.MultiWriter(os.Stdout, &stdoutBuf)
	stderr := io.MultiWriter(os.Stderr, &stderrBuf)
	if err := cmd.Start(); err != nil {
		xlog.Error("cmd.Start() failed with ", err)
		return false
	}
	var wg sync.WaitGroup
	wg.Add(1)
	go func() {
		_, errStdout = io.Copy(stdout, stdoutIn)
		log.Println(stdoutIn)
		wg.Done()
	}()
	_, errStderr = io.Copy(stderr, stderrIn)
	wg.Wait()
	if err := cmd.Wait(); err != nil {
		xlog.Error("cmd.Run() failed with ", err)
	}
	if errStdout != nil || errStderr != nil {
		xlog.Error("failed to capture stdout or stderr", errStderr, errStdout)
		return false
	}
	sendResult()
	return true
}
func sendResult() {
	if err := store.Dataset.Put(map[string]interface{}{
		"json": string(mustReadFile("video.json")),
		"srt":  string(mustReadFile("video.srt")),
		"tsv":  string(mustReadFile("video.tsv")),
		"txt":  string(mustReadFile("video.txt")),
		"vtt":  string(mustReadFile("video.vtt")),
	}); err != nil {
		log.Fatal(err)
	}
}
func mustReadFile(filename string) []byte {
	file, err := os.ReadFile(filename)
	if err != nil {
		return nil
	}
	return file
}
func downloadFile(fileURL string) {
	outputPath := "video.mp4"
	// Create the file
	out, err := os.Create(outputPath)
	if err != nil {
		log.Fatalf("Failed to create file: %v", err)
	}
	defer out.Close()
	// Get the data
	resp, err := http.Get(fileURL)
	if err != nil {
		log.Fatalf("Failed to download file: %v", err)
	}
	defer resp.Body.Close()
	// Check server response
	if resp.StatusCode != http.StatusOK {
		log.Fatalf("Bad status: %s", resp.Status)
	}
	// Write the body to file
	_, err = io.Copy(out, resp.Body)
	if err != nil {
		log.Fatalf("Failed to save file: %v", err)
	}
	log.Println("File downloaded successfully:", outputPath)
}