package imaging

import (
	"fmt"
	"os/exec"
)

// HEIC cannot be decoded in pure Go (HEVC), so conversion shells out to a
// host-installed CLI. The Go binary itself stays cgo-free; the converter is
// a runtime dependency (Debian: libvips-tools or libheif-examples).
type HeicConverter struct {
	kind string // "vips" | "heif-convert" | "custom"
	path string
}

// DetectHeicConverter honors an explicit HEIC_CONVERTER command, else
// autodetects vips then heif-convert. Returns nil when none is available;
// uploads of HEIC are then rejected with a clear message.
func DetectHeicConverter(explicit string) *HeicConverter {
	if explicit != "" {
		if p, err := exec.LookPath(explicit); err == nil {
			return &HeicConverter{kind: "custom", path: p}
		}
		return nil
	}
	if p, err := exec.LookPath("vips"); err == nil {
		return &HeicConverter{kind: "vips", path: p}
	}
	if p, err := exec.LookPath("heif-convert"); err == nil {
		return &HeicConverter{kind: "heif-convert", path: p}
	}
	return nil
}

func (h *HeicConverter) Name() string { return h.path }

// ToJPEG converts src (a .heic file) to a JPEG at dst.
func (h *HeicConverter) ToJPEG(src, dst string) error {
	var cmd *exec.Cmd
	switch h.kind {
	case "vips":
		cmd = exec.Command(h.path, "copy", src, dst+"[Q=95]")
	case "heif-convert":
		cmd = exec.Command(h.path, "-q", "95", src, dst)
	default:
		// custom converter contract: <cmd> <src> <dst>
		cmd = exec.Command(h.path, src, dst)
	}
	if out, err := cmd.CombinedOutput(); err != nil {
		return fmt.Errorf("heic conversion failed: %v: %s", err, truncate(string(out), 300))
	}
	return nil
}

func truncate(s string, n int) string {
	if len(s) > n {
		return s[:n]
	}
	return s
}
