///|
/// GLib Error Handling
///
/// Error_ represents a recoverable error with a domain, code, and message.
/// Automatically freed when garbage collected.

///|
/// Error_ - GLib's error structure.
/// Automatically freed when garbage collected.
pub suberror Error_

// =============================================================================
// FFI Declarations
// =============================================================================

///|
#borrow(message)
extern "c" fn moonbit_glib_error_new(
  domain : UInt,
  code : Int,
  message : Bytes,
) -> Error_ = "moonbit_glib_error_new"

///|
#borrow(error)
extern "c" fn moonbit_glib_error_copy(error : Error_) -> Error_ = "moonbit_glib_error_copy"

///|
#borrow(error)
extern "c" fn moonbit_glib_error_matches(
  error : Error_,
  domain : UInt,
  code : Int,
) -> Bool = "moonbit_glib_error_matches"

///|
#borrow(error)
extern "c" fn moonbit_glib_error_get_message(error : Error_) -> Bytes = "moonbit_glib_error_get_message"

///|
#borrow(error)
extern "c" fn moonbit_glib_error_get_code(error : Error_) -> Int = "moonbit_glib_error_get_code"

///|
#borrow(error)
extern "c" fn moonbit_glib_error_get_domain(error : Error_) -> UInt = "moonbit_glib_error_get_domain"

// =============================================================================
// Public Methods
// =============================================================================

///|
/// Create a new Error_.
///
/// # Example
///
/// ```mbt check
/// test {
///   let error = @glib.Error_::new(1U, 42, "Something went wrong")
///   assert_eq(error.code(), 42)
///   assert_eq(error.domain(), 1U)
///   assert_true(error.message().contains("Something went wrong"))
/// }
/// ```
pub fn Error_::new(domain : UInt, code : Int, message : String) -> Error_ {
  moonbit_glib_error_new(domain, code, @encoding/utf8.encode(message))
}

///|
/// Deep copy an Error_.
pub fn Error_::copy(self : Error_) -> Error_ {
  moonbit_glib_error_copy(self)
}

///|
/// Check if error matches the specified domain and code.
///
/// # Example
///
/// ```mbt check
/// test {
///   let error = @glib.Error_::new(5U, 100, "Network error")
///   assert_true(error.matches(5U, 100))
///   assert_false(error.matches(5U, 101))
///   assert_false(error.matches(6U, 100))
/// }
/// ```
pub fn Error_::matches(self : Error_, domain : UInt, code : Int) -> Bool {
  moonbit_glib_error_matches(self, domain, code)
}

///|
/// Get the error message.
pub fn Error_::message(self : Error_) -> String {
  @encoding/utf8.decode_lossy(moonbit_glib_error_get_message(self))
}

///|
/// Get the error code.
pub fn Error_::code(self : Error_) -> Int {
  moonbit_glib_error_get_code(self)
}

///|
/// Get the error domain (GQuark).
pub fn Error_::domain(self : Error_) -> UInt {
  moonbit_glib_error_get_domain(self)
}