package main

import (
	"flag"
	"log"
	"os"
	"path/filepath"
	"strings"
	"time"
	"unicode"

	"git.atri.dad/atridad/muse/lib/audio"
	"git.atri.dad/atridad/muse/lib/config"
)

func main() {
	// Define command line flags
	inputFile := flag.String("input", "", "Path to the YAML file containing the song definition")
	outputDir := flag.String("output", ".", "Directory to save the generated audio file")
	help := flag.Bool("help", false, "Show help message")

	flag.Parse()

	// Show help if requested or no input file provided
	if *help || *inputFile == "" {
		flag.Usage()
		os.Exit(0)
	}

	// Validate input file exists
	if _, err := os.Stat(*inputFile); os.IsNotExist(err) {
		log.Fatalf("Input file does not exist: %s", *inputFile)
	}

	// Create output directory if it doesn't exist
	if err := os.MkdirAll(*outputDir, 0755); err != nil {
		log.Fatalf("Failed to create output directory: %v", err)
	}

	// Load and parse YAML file
	log.Printf("Loading song from: %s\n", *inputFile)
	song, err := config.LoadSong(*inputFile)
	if err != nil {
		log.Fatalf("Failed to load song: %v", err)
	}
	log.Printf("Successfully loaded song: %s (BPM: %d, Length: %d bars)", song.Name, song.BPM, song.Length)

	// Generate audio
	generator := audio.NewGenerator()
	startTime := time.Now()
	log.Println("Starting audio generation...")

	audioData, err := generator.Generate(*song)
	if err != nil {
		log.Fatalf("Failed to generate audio: %v", err)
	}
	log.Printf("Generated %d samples (%.2f seconds)\n",
		len(audioData), float64(len(audioData))/float64(audio.SampleRate*audio.Channels))

	// Normalize audio to prevent clipping
	audio.Normalize(audioData)

	// Create output filename based on song name
	safeName := strings.Map(func(r rune) rune {
		if unicode.IsLetter(r) || unicode.IsNumber(r) || r == ' ' || r == '-' || r == '_' {
			return r
		}
		return '-'
	}, song.Name)

	// Ensure output directory exists
	if err := os.MkdirAll(*outputDir, 0755); err != nil {
		log.Fatalf("Failed to create output directory: %v", err)
	}

	outputPath := filepath.Join(*outputDir, safeName+".wav")

	// Write WAV file
	log.Printf("Writing WAV file to: %s\n", outputPath)
	if err := generator.WriteWAV(outputPath, audioData); err != nil {
		log.Fatalf("Failed to write WAV file: %v", err)
	}

	// Verify file was created
	if _, err := os.Stat(outputPath); os.IsNotExist(err) {
		log.Fatalf("Failed to verify output file was created: %v", err)
	}

	fileInfo, _ := os.Stat(outputPath)
	log.Printf("Success! Generated '%s' in %0.3fs\nFile size: %d bytes\nOutput: %s\n",
		song.Name,
		time.Since(startTime).Seconds(),
		fileInfo.Size(),
		outputPath,
	)
}
