package player

import (
	"bufio"
	"io"
	"os/exec"
	"strings"
)

// Play uses playerctl to play media
func Play() error {
	return exec.Command("playerctl", "play").Run()
}

// Pause uses playerctl to pause media
func Pause() error {
	return exec.Command("playerctl", "pause").Run()
}

// Next uses playerctl to skip to next media
func Next() error {
	return exec.Command("playerctl", "next").Run()
}

// Prev uses playerctl to skip to previous media
func Prev() error {
	return exec.Command("playerctl", "previous").Run()
}

// Metadata uses playerctl to detect music metadata changes
func Metadata(key string, onChange func(string)) error {
	// Execute playerctl command with key and follow flag
	cmd := exec.Command("playerctl", "metadata", key, "-F")
	// Get stdout pipe
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		return err
	}
	go func() {
		for {
			// Read line from command stdout
			line, _, err := bufio.NewReader(stdout).ReadLine()
			if err == io.EOF {
				continue
			}
			// Convert line to string
			data := string(line)
			// If key unknown, return suitable default
			if data == "No player could handle this command" || data == "" {
				data = "Unknown " + strings.Title(key)
			}
			// Run the onChange callback
			onChange(data)
		}
	}()
	// Start command asynchronously
	err = cmd.Start()
	if err != nil {
		return err
	}
	return nil
}

func Status(onChange func(bool)) error {
	// Execute playerctl status with follow flag
	cmd := exec.Command("playerctl", "status", "-F")
	// Get stdout pipe
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		return err
	}
	go func() {
		for {
			// Read line from command stdout
			line, _, err := bufio.NewReader(stdout).ReadLine()
			if err == io.EOF {
				continue
			}
			// Convert line to string
			data := string(line)
			// Run the onChange callback
			onChange(data == "Playing")
		}
	}()
	// Start command asynchronously
	err = cmd.Start()
	if err != nil {
		return err
	}
	return nil
}

func CurrentMetadata(key string) (string, error) {
	out, err := exec.Command("playerctl", "metadata", key).Output()
	if err != nil {
		return "", err
	}
	data := string(out)
	if data == "No player could handle this command" || data == "" {
		data = "Unknown " + strings.Title(key)
	}
	return data, nil
}

func CurrentStatus() (bool, error) {
	out, err := exec.Command("playerctl", "status").Output()
	if err != nil {
		return false, err
	}
	data := string(out)
	return data == "Playing", nil
}