use crate::modules::owner::events::OwnerChanged;
use crate::utils::Error;
use odra::contract_env::{caller, revert};
use odra::types::event::OdraEvent;
use odra::types::Address;
use odra::Variable;
#[odra::module]
pub struct Owner {
    pub owner: Variable<Address>,
    pub proposed_owner: Variable<Option<Address>>,
}
#[odra::module]
impl Owner {
    #[odra(init)]
    pub fn init(&mut self, owner: Address) {
        self.change_ownership(owner);
    }
    pub fn propose_owner(&mut self, owner: Address) {
        self.proposed_owner.set(Some(owner));
    }
    pub fn accept_owner(&mut self, caller: Address) {
        if let Some(proposed_owner) = self.proposed_owner.get_or_default() {
            if proposed_owner != caller {
                revert(Error::NotAProposedOwner);
            }
            self.change_ownership(proposed_owner);
        } else {
            revert(Error::NoProposedOwner);
        }
    }
    pub fn change_ownership(&mut self, owner: Address) {
        self.owner.set(owner);
        self.proposed_owner.set(None);
        OwnerChanged { new_owner: owner }.emit();
    }
    pub fn ensure_owner(&self) {
        if let Some(owner) = self.owner.get() {
            if owner != caller() {
                revert(Error::NotAnOwner)
            }
        } else {
            revert(Error::OwnerIsNotInitialized) }
    }
    pub fn get_owner(&self) -> Option<Address> {
        self.owner.get()
    }
}
pub mod events {
    use odra::types::Address;
    use odra::Event;
    #[derive(Debug, PartialEq, Eq, Event)]
    pub struct OwnerChanged {
        pub new_owner: Address,
    }
}