//! D-Bus proxy for the `org.openprinting.PrintBackend` interface.
//!
//! This module is generated by `zbus-xmlgen` and adapted to use named structs
//! for complex return types. Consumers should use [`crate::client::CpdbClient`]
//! instead of this proxy directly.

// The `#[proxy]` macro generates internal struct fields and service methods
// that cannot be given doc comments directly.
#![allow(missing_docs)]

use serde::{Deserialize, Serialize};
use zbus::proxy;
use zbus::zvariant::Type;

/// A printer option from `GetAllOptions`. D-Bus signature: `(sssia(s))`.
#[derive(Debug, Clone, Deserialize, Serialize, Type)]
pub struct RawOption {
    /// The option name (e.g. `"sides"`, `"copies"`).
    pub option_name: String,
    /// The option group name (e.g. `"General"`).
    pub group_name: String,
    /// The default value string.
    pub default_value: String,
    /// Number of supported values.
    pub num_supported: i32,
    /// The list of supported values as 1-tuples (D-Bus encoding).
    pub supported_values: Vec<(String,)>,
}

/// Print margins in hundredths of a millimetre. D-Bus signature: `(iiii)`.
#[derive(Debug, Clone, Deserialize, Serialize, Type)]
pub struct RawMargin {
    /// Left margin in hundredths of a mm.
    pub left: i32,
    /// Right margin in hundredths of a mm.
    pub right: i32,
    /// Top margin in hundredths of a mm.
    pub top: i32,
    /// Bottom margin in hundredths of a mm.
    pub bottom: i32,
}

/// A supported paper size from `GetAllOptions`. D-Bus signature: `(siiia(iiii))`.
///
/// Width and length are in hundredths of a millimetre.
#[derive(Debug, Clone, Deserialize, Serialize, Type)]
pub struct RawMedia {
    /// The media name (e.g. `"iso_a4_210x297mm"`).
    pub name: String,
    /// Width in hundredths of a mm.
    pub width: i32,
    /// Length in hundredths of a mm.
    pub length: i32,
    /// Number of margin entries.
    pub num_margins: i32,
    /// Available margin configurations.
    pub margins: Vec<RawMargin>,
}

/// A printer summary from `GetAllPrinters` or `GetFilteredPrinterList`.
/// D-Bus signature: `(sssssbss)`.
#[derive(Debug, Clone, Deserialize, Serialize, Type)]
pub struct RawPrinter(
    pub String, // id
    pub String, // name
    pub String, // info
    pub String, // location
    pub String, // make_and_model
    pub bool,   // is_accepting_jobs
    pub String, // state
    pub String, // backend_name
);

#[allow(missing_docs)]
/// Low-level proxy for `org.openprinting.PrintBackend`.
///
/// Prefer [`CpdbClient`](crate::client::CpdbClient) for high-level usage.
#[proxy(interface = "org.openprinting.PrintBackend", assume_defaults = true)]
pub trait PrintBackend {
    /// Returns all printers known to this backend.
    fn get_all_printers(&self) -> zbus::Result<(i32, Vec<(zbus::zvariant::OwnedValue,)>)>;

    /// Returns the backend name (e.g. "CUPS", "FILE").
    fn get_backend_name(&self) -> zbus::Result<String>;

    /// Returns printers matching the current filter settings.
    fn get_filtered_printer_list(&self) -> zbus::Result<(i32, Vec<(zbus::zvariant::OwnedValue,)>)>;

    /// Starts or stops printer discovery. Call `do_listing(true)` to trigger
    /// `PrinterAdded` signals for all known printers.
    ///
    /// This is a fire-and-forget method - the backend does not send a reply.
    #[zbus(name = "doListing", no_reply)]
    fn do_listing(&self, is_listed: bool) -> zbus::Result<()>;

    /// Fetches all options and media for a printer in a single call.
    ///
    /// Returns `(num_options, options, num_media, media)`.
    /// This is the primary method for getting printer capabilities.
    #[allow(clippy::type_complexity)]
    fn get_all_options(
        &self,
        printer_id: &str,
    ) -> zbus::Result<(i32, Vec<RawOption>, i32, Vec<RawMedia>)>;

    /// Fetches all localized translations for a printer's options.
    ///
    /// Returns a map of internal name -> human-readable label.
    fn get_all_translations(
        &self,
        printer_id: &str,
        locale: &str,
    ) -> zbus::Result<std::collections::HashMap<String, String>>;

    /// Returns the default printer ID for this backend.
    #[zbus(name = "getDefaultPrinter")]
    fn get_default_printer(&self) -> zbus::Result<String>;

    /// Returns the current state of a printer (e.g. "idle", "printing").
    #[zbus(name = "getPrinterState")]
    fn get_printer_state(&self, printer_id: &str) -> zbus::Result<String>;

    /// Returns whether a printer is currently accepting jobs.
    #[zbus(name = "isAcceptingJobs")]
    fn is_accepting_jobs(&self, printer_id: &str) -> zbus::Result<bool>;

    /// Returns a localized label for a single option name.
    #[zbus(name = "getOptionTranslation")]
    fn get_option_translation(
        &self,
        printer_name: &str,
        option_name: &str,
        locale: &str,
    ) -> zbus::Result<String>;

    /// Returns a localized label for a single option choice.
    #[zbus(name = "getChoiceTranslation")]
    fn get_choice_translation(
        &self,
        printer_name: &str,
        option_name: &str,
        choice_name: &str,
        locale: &str,
    ) -> zbus::Result<String>;

    /// Returns a localized label for an option group.
    #[zbus(name = "getGroupTranslation")]
    fn get_group_translation(
        &self,
        printer_name: &str,
        group_name: &str,
        locale: &str,
    ) -> zbus::Result<String>;

    /// Submits a print job and returns a writable file descriptor.
    ///
    /// The backend creates a job and returns the write end of a socketpair.
    /// The caller writes document data into `fd` and closes it when done.
    #[zbus(name = "printFd")]
    fn print_fd(
        &self,
        printer_id: &str,
        num_settings: i32,
        settings: &[(&str, &str)],
        title: &str,
    ) -> zbus::Result<(String, zbus::zvariant::OwnedFd)>;

    /// Submits a print job via a Unix socket path.
    #[zbus(name = "printSocket")]
    fn print_socket(
        &self,
        printer_id: &str,
        num_settings: i32,
        settings: &[(&str, &str)],
        title: &str,
    ) -> zbus::Result<(String, String)>;

    /// Show or hide remote (network-discovered) printers.
    ///
    /// This is a fire-and-forget method. The backend will emit `PrinterRemoved`
    /// or `PrinterAdded` signals to reflect the new filtered state.
    #[zbus(name = "showRemotePrinters", no_reply)]
    fn show_remote_printers(&self, is_visible: bool) -> zbus::Result<()>;

    /// Show or hide temporary (auto-discovered) printers.
    #[zbus(name = "showTemporaryPrinters", no_reply)]
    fn show_temporary_printers(&self, is_visible: bool) -> zbus::Result<()>;

    /// Keeps the backend alive (prevents auto-exit timeout).
    #[zbus(name = "keepAlive")]
    fn keep_alive(&self) -> zbus::Result<()>;

    /// Tells the backend to replace state from a previous dialog session.
    #[zbus(name = "replace", no_reply)]
    fn replace(&self, previous_dialog_id: &str) -> zbus::Result<()>;

    /// Ping (testing only, will be removed from spec).
    #[zbus(name = "ping", no_reply)]
    fn ping(&self, printer_id: &str) -> zbus::Result<()>;

    /// Emitted when a new printer is discovered by this backend.
    #[zbus(signal)]
    fn printer_added(
        &self,
        printer_id: &str,
        printer_name: &str,
        printer_info: &str,
        printer_location: &str,
        printer_make_and_model: &str,
        printer_is_accepting_jobs: bool,
        printer_state: &str,
        backend_name: &str,
    ) -> zbus::Result<()>;

    /// Emitted when a printer is removed from this backend.
    #[zbus(signal)]
    fn printer_removed(&self, printer_id: &str, backend_name: &str) -> zbus::Result<()>;

    /// Emitted when a printer's state changes (e.g. idle -> printing).
    #[zbus(signal)]
    fn printer_state_changed(
        &self,
        printer_id: &str,
        printer_state: &str,
        printer_is_accepting_jobs: bool,
        backend_name: &str,
    ) -> zbus::Result<()>;
}
