#!/usr/bin/env python3
# args_json: {"type":"object","properties":{"mode":{"type":"string","description":"active|screen|area|window (default: active)"},"output":{"type":"string","description":"Output file path"},"screen":{"type":"integer","description":"Screen index for screen mode"},"title":{"type":"string","description":"Window title substring for window mode"},"include_cursor":{"type":"boolean","description":"Include cursor in capture"},"include_decoration":{"type":"boolean","description":"Include window decoration (default: true)"}}}
# ollie:prompt
# ## gui_screenshot
#
# Capture screenshots via KWin (Wayland-safe).
#
# **Args**: `[mode]` or `[mode, "--output=path"]`
# - mode: `active`, `screen`, `area`, `window` (default: active)
#
# ```
# gui_screenshot(mode="active")
# gui_screenshot(mode="screen", output="--output=/tmp/shot.png")
# ```
# ollie:end
"""KDE screenshot tool using org.kde.KWin.ScreenShot2.

Modes:
  active   - capture the currently active window (default)
  screen   - capture entire screen (or specific with --screen=N)
  area     - capture a region (interactive picker)
  window   - capture window by title substring match

Output defaults to /tmp/ollie_screenshot_<timestamp>.png
"""
import sys
import os
import time
import subprocess
import tempfile

SERVICE = "org.kde.KWin"
OBJ_PATH = "/org/kde/KWin/ScreenShot2"
IFACE = "org.kde.KWin.ScreenShot2"


def parse_args():
    sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
    from _lib.args import parse_args as _parse
    _a = _parse()

    class _Args:
        mode = _a.get("mode", "active")
        output = _a.get("output", "")
        screen = _a.get_int("screen", 0)
        title = _a.get("title", "")
        include_cursor = _a.get_bool("include_cursor")
        include_decoration = _a.get_bool("include_decoration", True)
    return _Args()


def get_output_path(args):
    if args.output:
        return args.output
    ts = int(time.time())
    return f"/tmp/ollie_screenshot_{ts}.png"


def capture_with_spectacle(mode, output, title=""):
    """Fallback: use spectacle CLI if ScreenShot2 is unavailable."""
    cmd = ["spectacle", "-b", "-n", "-o", output]
    if mode == "active":
        cmd.append("-a")
    elif mode == "screen":
        cmd.append("-f")
    elif mode == "area":
        cmd.append("-r")
    elif mode == "window":
        cmd.append("-a")  # fall back to active window

    result = subprocess.run(cmd, capture_output=True, text=True, timeout=15)
    if result.returncode != 0:
        return None
    return output


def find_window_id_by_title(title):
    """Use KWin scripting to find window UUID by title."""
    script = f"""
    const clients = workspace.windowList();
    for (let i = 0; i < clients.length; i++) {{
        if (clients[i].caption.toLowerCase().includes('{title.lower()}')) {{
            print(clients[i].internalId);
            break;
        }}
    }}
    """
    # Load script via D-Bus
    load_cmd = [
        "gdbus", "call", "--session",
        "--dest", "org.kde.KWin",
        "--object-path", "/Scripting",
        "--method", "org.kde.kwin.Scripting.loadScript", "", script
    ]
    # This is complex; for now fall back to xdotool/wmctrl
    try:
        result = subprocess.run(
            ["xdotool", "search", "--name", title],
            capture_output=True, text=True, timeout=5
        )
        if result.stdout.strip():
            return result.stdout.strip().split("\n")[0]
    except (FileNotFoundError, subprocess.TimeoutExpired):
        pass
    return None


def capture_via_dbus(mode, output, args):
    """Use KWin ScreenShot2 portal-style capture with pipe fd."""
    hints = {
        "include-cursor": args.include_cursor,
        "include-decoration": args.include_decoration,
    }

    # ScreenShot2 methods use file descriptors which gdbus can't handle directly.
    # Use the portal interface instead, or fall back to spectacle.
    # Try the portal first:
    portal_cmd = [
        "gdbus", "call", "--session",
        "--dest", "org.freedesktop.portal.Desktop",
        "--object-path", "/org/freedesktop/portal/desktop",
        "--method", "org.freedesktop.portal.Screenshot.Screenshot",
        "",  # parent_window
        "{'interactive': <false>}",
    ]

    # Spectacle is more reliable for non-interactive capture
    result = capture_with_spectacle(mode, output, args.title)
    if result and os.path.isfile(result):
        return result

    # Last resort: try import (ImageMagick) for X11
    if os.environ.get("DISPLAY"):
        if mode == "active":
            wid = subprocess.run(
                ["xdotool", "getactivewindow"],
                capture_output=True, text=True
            ).stdout.strip()
            if wid:
                r = subprocess.run(["import", "-window", wid, output],
                                   capture_output=True, timeout=10)
                if r.returncode == 0:
                    return output
        elif mode == "screen":
            r = subprocess.run(["import", "-window", "root", output],
                               capture_output=True, timeout=10)
            if r.returncode == 0:
                return output

    return None


def main():
    args = parse_args()
    output = get_output_path(args)

    result = capture_via_dbus(args.mode, output, args)

    if result and os.path.isfile(result):
        size = os.path.getsize(result)
        print(f"{result} ({size} bytes)")
    else:
        print("ERROR: screenshot capture failed", file=sys.stderr)
        print("Ensure spectacle or imagemagick is installed", file=sys.stderr)
        sys.exit(1)


if __name__ == "__main__":
    main()
