use anchor_lang::prelude::*;

declare_id!("95nsDLQteRVijqfn6yNghSW4xakdEWXrztGmeh5YjA35");

/// This boundary is deliberately immutable. It is not a score, governance
/// preference, or operational toggle.
pub const MISSION_BOUNDARY: &str =
    "Morals over metrics. Privacy over surveillance. Freedom over control. Human thriving over extraction.";

#[program]
pub mod mission_enforcement {
    use super::*;

    pub fn initialize(ctx: Context<Initialize>, mission_statement: String) -> Result<()> {
        let deployment_authorized = false;
        require!(deployment_authorized, VaultfireError::BootstrapDisabled);
        require!(
            mission_statement.len() <= 500,
            VaultfireError::MissionTooLong
        );
        require!(
            mission_statement == MISSION_BOUNDARY,
            VaultfireError::MissionBoundaryViolation
        );
        let state = &mut ctx.accounts.mission_state;
        state.authority = ctx.accounts.authority.key();
        state.mission_statement = MISSION_BOUNDARY.to_string();
        state.version = 1;
        state.enforced = true;
        state.updated_at = Clock::get()?.unix_timestamp;
        emit!(MissionInitialized {
            authority: state.authority,
            mission_statement,
            version: 1,
        });
        Ok(())
    }

    /// The authority cannot dilute or replace the protocol boundary.
    pub fn update_mission(_ctx: Context<UpdateMission>, _new_mission: String) -> Result<()> {
        err!(VaultfireError::MissionBoundaryImmutable)
    }

    pub fn enforce_mission(ctx: Context<EnforceMission>) -> Result<()> {
        let state = &ctx.accounts.mission_state;
        require!(state.enforced, VaultfireError::MissionNotEnforced);
        require!(
            state.mission_statement == MISSION_BOUNDARY,
            VaultfireError::MissionBoundaryViolation
        );
        emit!(MissionEnforced {
            authority: state.authority,
            mission_statement: state.mission_statement.clone(),
            enforced_at: Clock::get()?.unix_timestamp,
        });
        Ok(())
    }

    /// No signer, including the bootstrap authority, can turn off the boundary.
    pub fn toggle_enforcement(_ctx: Context<UpdateMission>, _enforced: bool) -> Result<()> {
        err!(VaultfireError::MissionBoundaryImmutable)
    }
}

#[derive(Accounts)]
pub struct Initialize<'info> {
    #[account(
        init,
        payer = authority,
        space = 8 + 32 + 4 + 500 + 4 + 1 + 8,
        seeds = [b"mission"],
        bump
    )]
    pub mission_state: Account<'info, MissionState>,
    #[account(mut)]
    pub authority: Signer<'info>,
    pub system_program: Program<'info, System>,
}

#[derive(Accounts)]
pub struct UpdateMission<'info> {
    #[account(
        mut,
        seeds = [b"mission"],
        bump,
        has_one = authority
    )]
    pub mission_state: Account<'info, MissionState>,
    pub authority: Signer<'info>,
}

#[derive(Accounts)]
pub struct EnforceMission<'info> {
    #[account(
        seeds = [b"mission"],
        bump
    )]
    pub mission_state: Account<'info, MissionState>,
}

#[account]
pub struct MissionState {
    pub authority: Pubkey,
    pub mission_statement: String,
    pub version: u32,
    pub enforced: bool,
    pub updated_at: i64,
}

#[event]
pub struct MissionInitialized {
    pub authority: Pubkey,
    pub mission_statement: String,
    pub version: u32,
}

#[event]
pub struct MissionUpdated {
    pub authority: Pubkey,
    pub new_mission: String,
    pub version: u32,
}

#[event]
pub struct MissionEnforced {
    pub authority: Pubkey,
    pub mission_statement: String,
    pub enforced_at: i64,
}

#[event]
pub struct EnforcementToggled {
    pub authority: Pubkey,
    pub enforced: bool,
}

#[error_code]
pub enum VaultfireError {
    #[msg("Mission statement exceeds maximum length of 500 characters")]
    MissionTooLong,
    #[msg("Mission is not currently enforced")]
    MissionNotEnforced,
    #[msg("Arithmetic overflow")]
    ArithmeticOverflow,
    #[msg("Mission must exactly match the immutable Vaultfire boundary")]
    MissionBoundaryViolation,
    #[msg("The immutable Vaultfire mission boundary cannot be changed or disabled")]
    MissionBoundaryImmutable,
    #[msg("Bootstrap is disabled until a source-backed partner authority design is approved")]
    BootstrapDisabled,
}

#[cfg(test)]
mod tests {
    use super::MISSION_BOUNDARY;

    #[test]
    fn immutable_boundary_contains_every_required_priority() {
        assert!(MISSION_BOUNDARY.contains("Morals over metrics"));
        assert!(MISSION_BOUNDARY.contains("Privacy over surveillance"));
        assert!(MISSION_BOUNDARY.contains("Freedom over control"));
        assert!(MISSION_BOUNDARY.contains("Human thriving over extraction"));
    }
}
