// Copyright (c) Subzero Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

use rialo_s_pubkey::Pubkey;

#[repr(u64)]
#[cfg_attr(feature = "frozen-abi", derive(rialo_frozen_abi_macro::AbiExample))]
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum RexWasmV1LoaderStatus {
    /// Program is in maintenance
    Retracted,
    /// Program is ready to be executed
    Deployed,
    /// Same as `Deployed`, but can not be retracted anymore
    Finalized,
}

/// RexWasmV1Loader account states
#[repr(C)]
#[cfg_attr(feature = "frozen-abi", derive(rialo_frozen_abi_macro::AbiExample))]
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub struct RexWasmV1LoaderState {
    /// Slot in which the program was last deployed, retracted or initialized.
    pub slot: u64,
    /// Address of signer which can send program management instructions when the status is not finalized.
    /// Otherwise a forwarding to the next version of the finalized program.
    pub authority_address_or_next_version: Pubkey,
    /// Deployment status.
    pub status: RexWasmV1LoaderStatus,
    // The raw program data follows this serialized structure in the
    // account's data.
}

impl RexWasmV1LoaderState {
    /// Size of a serialized program account header.
    pub const fn program_data_offset() -> usize {
        std::mem::size_of::<Self>()
    }
}

#[cfg(test)]
mod tests {
    use memoffset::offset_of;

    use super::*;

    #[test]
    fn test_layout() {
        assert_eq!(offset_of!(RexWasmV1LoaderState, slot), 0x00);
        assert_eq!(
            offset_of!(RexWasmV1LoaderState, authority_address_or_next_version),
            0x08
        );
        assert_eq!(offset_of!(RexWasmV1LoaderState, status), 0x28);
        assert_eq!(RexWasmV1LoaderState::program_data_offset(), 0x30);
    }
}
