package main

import (
	"fmt"
	"io"
	"log"
	"os"

	"git.kingecg.top/kingecg/goffmpeg/pkg/ffmpeg"
	"git.kingecg.top/kingecg/goffmpeg/pkg/ffmpeg/stream"
)

// Example 1: Read media info from a URL (local file or network stream)
func exampleReadMediaInfo(inputURL string) {
	fmt.Printf("\n=== Example 1: Reading Media Info ===\n")

	sr, err := stream.NewStreamReader(stream.TranscodeOptions{
		InputURL: inputURL,
	})
	if err != nil {
		log.Printf("Failed to create stream reader: %v", err)
		return
	}
	defer sr.Close()

	info, err := sr.MediaInfo()
	if err != nil {
		log.Printf("Failed to get media info: %v", err)
		return
	}

	fmt.Printf("Media Info:\n")
	fmt.Printf("  Duration: %v\n", info.Duration)
	fmt.Printf("  Start Time: %v\n", info.StartTime)
	fmt.Printf("  Bit Rate: %d bps\n", info.BitRate)
	fmt.Printf("  Streams: %d\n", len(info.Streams))

	for i, s := range info.Streams {
		fmt.Printf("  Stream %d:\n", i)
		fmt.Printf("    Type: %v\n", s.Type)
		fmt.Printf("    Codec: %s (%s)\n", s.CodecName, s.CodecLongName)
		if s.Type == ffmpeg.CodecTypeVideo {
			fmt.Printf("    Resolution: %dx%d\n", s.Width, s.Height)
			fmt.Printf("    Pixel Format: %s\n", s.PixelFormat)
		} else if s.Type == ffmpeg.CodecTypeAudio {
			fmt.Printf("    Sample Rate: %d\n", s.SampleRate)
			fmt.Printf("    Channels: %d\n", s.Channels)
			fmt.Printf("    Channel Layout: %s\n", s.ChannelLayout)
		}
	}
}

// Example 2: Stream copy (remux) from input to output
func exampleStreamCopy(inputURL, outputURL string) {
	fmt.Printf("\n=== Example 2: Stream Copy (Remux) ===\n")

	sr, err := stream.NewStreamReader(stream.TranscodeOptions{
		InputURL: inputURL,
	})
	if err != nil {
		log.Printf("Failed to create stream reader: %v", err)
		return
	}
	defer sr.Close()

	// Create output file
	outFile, err := os.Create(outputURL)
	if err != nil {
		log.Printf("Failed to create output file: %v", err)
		return
	}
	defer outFile.Close()

	// Read data from stream reader and write to output
	fmt.Printf("Copying stream from %s to %s...\n", inputURL, outputURL)

	buf := make([]byte, 32768)
	written := 0
	for {
		n, err := sr.Read(buf)
		if n > 0 {
			outFile.Write(buf[:n])
			written += n
			fmt.Printf("\rWritten: %d bytes", written)
		}
		if err != nil {
			if err == io.EOF {
				fmt.Println("\nStream copy completed!")
				break
			}
			log.Printf("\nError reading stream: %v", err)
			break
		}
	}
}

// Example 3: Read from io.Reader
func exampleReadFromReader(inputURL string) {
	fmt.Printf("\n=== Example 3: Read from io.Reader ===\n")

	// Open input file as io.Reader
	inFile, err := os.Open(inputURL)
	if err != nil {
		log.Printf("Failed to open input file: %v", err)
		return
	}
	defer inFile.Close()

	sr, err := stream.NewStreamReader(stream.TranscodeOptions{
		InputIO: inFile,
	})
	if err != nil {
		log.Printf("Failed to create stream reader: %v", err)
		return
	}
	defer sr.Close()

	info, err := sr.MediaInfo()
	if err != nil {
		log.Printf("Failed to get media info: %v", err)
		return
	}

	fmt.Printf("Media info from io.Reader:\n")
	fmt.Printf("  Duration: %v\n", info.Duration)
	fmt.Printf("  Streams: %d\n", len(info.Streams))
}

func main() {
	if len(os.Args) < 2 {
		fmt.Println("Usage: stream-reader <command> [args]")
		fmt.Println("\nCommands:")
		fmt.Println("  info <input>           - Read and display media info")
		fmt.Println("  copy <input> <output> - Copy/remux stream")
		fmt.Println("  reader <input>        - Read from io.Reader")
		fmt.Println("\nExamples:")
		fmt.Println("  stream-reader info /path/to/video.mp4")
		fmt.Println("  stream-reader copy input.mp4 output.flv")
		fmt.Println("  stream-reader reader /path/to/video.mp4")
		os.Exit(1)
	}

	command := os.Args[1]

	switch command {
	case "info":
		if len(os.Args) < 3 {
			fmt.Println("Usage: stream-reader info <input>")
			os.Exit(1)
		}
		exampleReadMediaInfo(os.Args[2])

	case "copy":
		if len(os.Args) < 4 {
			fmt.Println("Usage: stream-reader copy <input> <output>")
			os.Exit(1)
		}
		exampleStreamCopy(os.Args[2], os.Args[3])

	case "reader":
		if len(os.Args) < 3 {
			fmt.Println("Usage: stream-reader reader <input>")
			os.Exit(1)
		}
		exampleReadFromReader(os.Args[2])

	default:
		fmt.Printf("Unknown command: %s\n", command)
		os.Exit(1)
	}
}
