// Copyright 2026 International Digital Economy Academy
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
///|
/// Handle for idle watchers in the libuv event loop.
///
/// Idle watchers run their callbacks once per event loop iteration, right before
/// the event loop blocks for I/O. They are useful for performing background
/// tasks when the event loop is idle.
///
/// Example:
///
/// ```moonbit nocheck
/// let uv = @uv.Loop::new()
/// let errors = []
/// let idle = @uv.Idle::new(uv)
/// idle.start(fn(_) {
/// println("Idle callback running")
/// idle.stop() catch {
/// error => errors.push(error)
/// }
/// idle.close(() => ())
/// })
/// uv.run(Default)
/// uv.close()
/// for error in errors {
/// raise error
/// }
/// ```
type Idle
///|
pub impl ToHandle for Idle with to_handle(idle : Idle) -> Handle = "%identity"
///|
pub impl ToHandle for Idle with of_handle(handle : Handle) -> Idle = "%identity"
///|
extern "c" fn uv_idle_make() -> Idle = "moonbit_uv_idle_make"
///|
#owned(uv, idle)
extern "c" fn uv_idle_init(uv : Loop, idle : Idle) -> Int = "moonbit_uv_idle_init"
///|
pub fn Idle::new(self : Loop) -> Idle raise Errno {
let idle = uv_idle_make()
let status = uv_idle_init(self, idle)
if status < 0 {
raise Errno::of_int(status)
}
return idle
}
///|
#owned(idle)
extern "c" fn uv_idle_start(idle : Idle, cb : (Idle) -> Unit) -> Int = "moonbit_uv_idle_start"
///|
#owned(idle)
extern "c" fn uv_idle_stop(idle : Idle) -> Int = "moonbit_uv_idle_stop"
///|
pub fn Idle::start(self : Idle, cb : (Idle) -> Unit) -> Unit raise Errno {
let status = uv_idle_start(self, fn(idle) { cb(idle) })
if status < 0 {
raise Errno::of_int(status)
}
}
///|
pub fn Idle::stop(self : Idle) -> Unit raise Errno {
let status = uv_idle_stop(self)
if status < 0 {
raise Errno::of_int(status)
}
}