# Right-click a video to shrink it, or a picture to convert it.
#
# macOS puts both behind Quick Actions in Finder. On Linux the usual answer is
# a web uploader or an ffmpeg incantation somebody looks up again every time.
#
# The menu only appears for files this can actually handle, decided by mime
# type rather than by extension, so a .mov named .txt does not get an entry it
# would fail on. The work itself is bin/panama-transcode, which writes beside
# the input and never over it.

import os
import subprocess
from urllib.parse import unquote, urlparse

from gi.repository import GObject, Nautilus

HELPER = os.path.expanduser("~/.local/share/Panama/bin/panama-transcode")

VIDEO_SIZES = [("1080p", "1080p"), ("720p", "720p"), ("480p", "480p")]
IMAGE_FORMATS = [("jpg", "JPEG"), ("png", "PNG"), ("webp", "WebP")]


def _local_path(file_info):
    uri = file_info.get_uri()
    parsed = urlparse(uri)
    if parsed.scheme != "file":
        return None
    path = unquote(parsed.path)
    return path if os.path.isfile(path) else None


class PanamaTranscodeExtension(GObject.GObject, Nautilus.MenuProvider):
    def get_file_items(self, files):
        # One at a time: a submenu that starts nine encodes from one click is
        # a way to make a machine unusable by accident.
        if len(files) != 1:
            return []

        info = files[0]
        path = _local_path(info)
        if path is None or not os.access(HELPER, os.X_OK):
            return []

        mime = info.get_mime_type() or ""
        if mime.startswith("video/"):
            return [self._submenu(path, "video", "Convert video", VIDEO_SIZES)]
        if mime.startswith("image/"):
            return [self._submenu(path, "image", "Convert image", IMAGE_FORMATS)]
        return []

    def _submenu(self, path, kind, label, options):
        top = Nautilus.MenuItem(name=f"Panama::Transcode{kind}", label=label)
        menu = Nautilus.Menu()
        top.set_submenu(menu)

        for value, shown in options:
            item = Nautilus.MenuItem(
                name=f"Panama::Transcode{kind}{value}",
                label=shown,
                tip=f"Write a {shown} copy beside this file",
            )
            item.connect("activate", self._run, kind, path, value)
            menu.append_item(item)
        return top

    def _run(self, _menu, kind, path, value):
        # Detached on purpose: a long encode must not block the file manager,
        # and panama-transcode reports its own progress through notifications.
        try:
            subprocess.Popen(
                [HELPER, kind, path, value],
                stdout=subprocess.DEVNULL,
                stderr=subprocess.DEVNULL,
                start_new_session=True,
            )
        except OSError:
            pass
