// Copyright (c) Subzero Labs, Inc.
// SPDX-License-Identifier: Apache-2.0
// This file is either (a) original to Subzero Labs, Inc. or (b) derived from the Anza codebase and modified by Subzero Labs, Inc.

//! `SystemInstruction` Javascript interface
#![cfg(target_arch = "wasm32")]
#![allow(non_snake_case)]
use rialo_s_instruction::Instruction;
use rialo_s_pubkey::Pubkey;
use wasm_bindgen::prelude::*;

use crate::instruction::{
    advance_nonce_account, allocate, allocate_with_seed, assign, assign_with_seed,
    authorize_nonce_account, create_account, create_account_with_seed, create_nonce_account,
    transfer, transfer_with_seed, withdraw_nonce_account, SystemInstruction,
};

#[wasm_bindgen]
impl SystemInstruction {
    pub fn createAccount(
        from_pubkey: &Pubkey,
        to_pubkey: &Pubkey,
        kelvins: u64,
        space: u64,
        owner: &Pubkey,
    ) -> Instruction {
        create_account(from_pubkey, to_pubkey, kelvins, space, owner)
    }

    pub fn createAccountWithSeed(
        from_pubkey: &Pubkey,
        to_pubkey: &Pubkey,
        base: &Pubkey,
        seed: &str,
        kelvins: u64,
        space: u64,
        owner: &Pubkey,
    ) -> Instruction {
        create_account_with_seed(from_pubkey, to_pubkey, base, seed, kelvins, space, owner)
    }

    pub fn assign(pubkey: &Pubkey, owner: &Pubkey) -> Instruction {
        assign(pubkey, owner)
    }

    pub fn assignWithSeed(
        pubkey: &Pubkey,
        base: &Pubkey,
        seed: &str,
        owner: &Pubkey,
    ) -> Instruction {
        assign_with_seed(pubkey, base, seed, owner)
    }

    pub fn transfer(from_pubkey: &Pubkey, to_pubkey: &Pubkey, kelvins: u64) -> Instruction {
        transfer(from_pubkey, to_pubkey, kelvins)
    }

    pub fn transferWithSeed(
        from_pubkey: &Pubkey,
        from_base: &Pubkey,
        from_seed: String,
        from_owner: &Pubkey,
        to_pubkey: &Pubkey,
        kelvins: u64,
    ) -> Instruction {
        transfer_with_seed(
            from_pubkey,
            from_base,
            from_seed,
            from_owner,
            to_pubkey,
            kelvins,
        )
    }

    pub fn allocate(pubkey: &Pubkey, space: u64) -> Instruction {
        allocate(pubkey, space)
    }

    pub fn allocateWithSeed(
        address: &Pubkey,
        base: &Pubkey,
        seed: &str,
        space: u64,
        owner: &Pubkey,
    ) -> Instruction {
        allocate_with_seed(address, base, seed, space, owner)
    }

    pub fn createNonceAccount(
        from_pubkey: &Pubkey,
        nonce_pubkey: &Pubkey,
        authority: &Pubkey,
        kelvins: u64,
    ) -> js_sys::Array {
        let instructions = create_nonce_account(from_pubkey, nonce_pubkey, authority, kelvins);
        instructions.into_iter().map(JsValue::from).collect()
    }

    pub fn advanceNonceAccount(nonce_pubkey: &Pubkey, authorized_pubkey: &Pubkey) -> Instruction {
        advance_nonce_account(nonce_pubkey, authorized_pubkey)
    }

    pub fn withdrawNonceAccount(
        nonce_pubkey: &Pubkey,
        authorized_pubkey: &Pubkey,
        to_pubkey: &Pubkey,
        kelvins: u64,
    ) -> Instruction {
        withdraw_nonce_account(nonce_pubkey, authorized_pubkey, to_pubkey, kelvins)
    }

    pub fn authorizeNonceAccount(
        nonce_pubkey: &Pubkey,
        authorized_pubkey: &Pubkey,
        new_authority: &Pubkey,
    ) -> Instruction {
        authorize_nonce_account(nonce_pubkey, authorized_pubkey, new_authority)
    }
}
