#!/usr/bin/python3
"""SSH_ASKPASS helper for passwords stored in Secret Service."""

from __future__ import annotations

import sys
from pathlib import Path
import uuid
import os


HOST_KEY_SUFFIX = (
    "Are you sure you want to continue connecting "
    "(yes/no/[fingerprint])?"
)


def is_host_key_confirmation(prompt: str | None) -> bool:
    if not prompt:
        return False
    return (
        prompt.startswith("The authenticity of host ")
        and "can't be established." in prompt
        and prompt.rstrip().endswith(HOST_KEY_SUFFIX)
    )


def relay_host_key_prompt(prompt: str) -> int:
    try:
        sys.stderr.write(prompt)
        sys.stderr.flush()

        response = sys.stdin.readline()
        if not response:
            return 1

        sys.stdout.write(response)
        sys.stdout.flush()
        return 0
    except (OSError, UnicodeError, ValueError):
        return 1

def _add_import_path() -> None:
    script_dir = Path(__file__).resolve().parent
    candidates = (script_dir.parent, Path("/usr/lib/synex-connections"))
    for candidate in candidates:
        if (candidate / "synexconnections").is_dir():
            sys.path.insert(0, str(candidate))
            return


def _confirm(prompt: str | None) -> int:
    import gi
    from synexconnections.i18n import _, setup

    setup()
    if prompt is None:
        prompt = _("Confirm SSH operation")

    gi.require_version("Adw", "1")
    gi.require_version("GLib", "2.0")
    from gi.repository import Adw, GLib

    result = {"accepted": False}

    class ConfirmApplication(Adw.Application):
        def __init__(self) -> None:
            super().__init__(application_id="ar.synex.Connections.Askpass")
            self.connect("activate", self._activate)

        def _activate(self, application) -> None:
            dialog = Adw.AlertDialog(heading=_("Confirm SSH operation"), body=prompt)
            dialog.add_response("cancel", _("Cancel"))
            dialog.add_response("confirm", _("Confirm"))
            dialog.set_default_response("cancel")
            dialog.set_close_response("cancel")
            dialog.choose(None, None, self._chosen)

        def _chosen(self, dialog, async_result) -> None:
            try:
                result["accepted"] = dialog.choose_finish(async_result) == "confirm"
            except GLib.Error:
                result["accepted"] = False
            self.quit()

    ConfirmApplication().run(None)
    return 0 if result["accepted"] else 1


def main() -> int:
    prompt_type = os.environ.get("SSH_ASKPASS_PROMPT", "")
    connection_id = os.environ.get("SYNEX_CONNECTION_ID", "")
    try:
        canonical_id = str(uuid.UUID(connection_id))
    except ValueError:
        return 1
    if prompt_type == "":
        prompt = sys.argv[1] if len(sys.argv) > 1 else ""
        if is_host_key_confirmation(prompt):
            return relay_host_key_prompt(prompt)
        _add_import_path()
        from synexconnections.secret_store import SecretStore, SecretStoreError

        try:
            password = SecretStore().lookup_password_sync(canonical_id)
        except SecretStoreError:
            return 1
        sys.stdout.write(password)
        sys.stdout.flush()
        return 0
    if prompt_type == "confirm":
        prompt = sys.argv[1] if len(sys.argv) > 1 else None
        return _confirm(prompt)
    return 1


if __name__ == "__main__":
    raise SystemExit(main())
