// Copyright 2021-2023 Protocol Labs
// SPDX-License-Identifier: Apache-2.0, MIT
//! Syscalls for querying and modifying the current actor.

// for documentation links
#[cfg(doc)]
use crate::sys::ErrorNumber::*;

super::fvm_syscalls! {
    module = "self";

    /// Gets the current root for the calling actor.
    ///
    /// Returns the size of the CID.
    ///
    /// # Arguments
    ///
    /// - `cid` is the location in memory where the state-root will be written.
    /// - `max_cid_len` is length of the output CID buffer.
    ///
    /// # Errors
    ///
    /// | Error                | Reason                                                |
    /// |----------------------|-------------------------------------------------------|
    /// | [`IllegalOperation`] | actor hasn't set the root yet, or has been deleted    |
    /// | [`IllegalArgument`]  | if the passed buffer isn't valid, in memory, etc.     |
    /// | [`BufferTooSmall`]  | if the output buffer isn't large enough to fit the CID |
    pub fn root(cid: *mut u8, cid_max_len: u32) -> Result<u32>;

    /// Sets the root CID for the calling actor. The new root must be in the reachable set.
    ///
    /// # Arguments
    ///
    /// - `cid` is the location in memory of the new state-root CID.
    ///
    /// # Errors
    ///
    /// | Error                | Reason                                         |
    /// |----------------------|------------------------------------------------|
    /// | [`IllegalOperation`] | actor has been deleted                         |
    /// | [`ReadOnly`]         | the actor is executing in read-only mode       |
    /// | [`NotFound`]         | specified root CID is not in the reachable set |
    pub fn set_root(cid: *const u8) -> Result<()>;

    /// Gets the current balance for the calling actor.
    ///
    /// # Errors
    ///
    /// None.
    pub fn current_balance() -> Result<super::TokenAmount>;

    /// Destroys the calling actor. If `burn_funds` is true, any unspent balance will be burnt
    /// (destroyed). Otherwise, if `burnt_funds` is false and there are unspent funds, this syscall
    /// will fail.
    ///
    /// # Arguments
    ///
    /// - `burn_funds` must be true to delete an actor with unspent funds.
    ///
    /// # Errors
    ///
    /// | Error                 | Reason                                    |
    /// |-----------------------|-------------------------------------------|
    /// | [`IllegalOperation`]  | the actor has unspent funds               |
    /// | [`ReadOnly`]          | the actor is executing in read-only mode  |
    pub fn self_destruct(burn_funds: bool) -> Result<()>;
}
