use crate::driver::pot_dsl::{par, pot, t, Pot};

use crate::execution;

/// The pot containing general execution environment tests. As upgraded System
/// Tests allow for the parallel execution of tests, we put all of them into one
/// pot again.
pub fn general_execution_pot() -> Pot {
    pot(
        "general_execution_pot",
        execution::config_system_verified_application_subnets(),
        par(vec![
            t(
                "request_signature_test",
                execution::request_signature_test::test
            ),
            t(
                "malicious_input_test",
                execution::malicious_input::test
            ),
            t(
                "test_raw_rand_api",
                execution::api_tests::test_raw_rand_api
            ),
            t(
                "can_access_big_heap_and_big_stable_memory",
                execution::big_stable_memory::can_access_big_heap_and_big_stable_memory
            ),
            t(
                "can_access_big_stable_memory",
                execution::big_stable_memory::can_access_big_stable_memory
            ),
            t(
                "can_handle_overflows_when_indexing_stable_memory",
                execution::big_stable_memory::can_handle_overflows_when_indexing_stable_memory
            ),
            t(
                "can_handle_out_of_bounds_access",
                execution::big_stable_memory::can_handle_out_of_bounds_access
            ),
            t(
                "canister_traps_if_32_bit_api_used_on_big_memory",
                execution::big_stable_memory::canister_traps_if_32_bit_api_used_on_big_memory
            ),
            t(
                "create_canister_via_ingress_fails",
                execution::canister_lifecycle::create_canister_via_ingress_fails
            ),
            t(
                "create_canister_via_canister_succeeds",
                execution::canister_lifecycle::create_canister_via_canister_succeeds
            ),
            t(
                "create_canister_with_controller_and_controllers_fails",
                execution::canister_lifecycle::create_canister_with_controller_and_controllers_fails
            ),
            t(
                "create_canister_with_one_controller",
                execution::canister_lifecycle::create_canister_with_one_controller
            ),
            t(
                "create_canister_with_no_controllers",
                execution::canister_lifecycle::create_canister_with_no_controllers
            ),
            t(
                "create_canister_with_multiple_controllers",
                execution::canister_lifecycle::create_canister_with_multiple_controllers
            ),
            t(
                "create_canister_with_too_many_controllers_fails",
                execution::canister_lifecycle::create_canister_with_too_many_controllers_fails
            ),
            t(
                "create_canister_with_none_settings_field",
                execution::canister_lifecycle::create_canister_with_none_settings_field
            ),
            t(
                "create_canister_with_empty_settings",
                execution::canister_lifecycle::create_canister_with_empty_settings
            ),
            t(
                "create_canister_with_settings",
                execution::canister_lifecycle::create_canister_with_settings
            ),
            t(
                "create_canister_with_freezing_threshold",
                execution::canister_lifecycle::create_canister_with_freezing_threshold
            ),
            t(
                "create_canister_with_invalid_freezing_threshold_fails",
                execution::canister_lifecycle::create_canister_with_invalid_freezing_threshold_fails
            ),
            t(
                "managing_a_canister_with_wrong_controller_fails",
                execution::canister_lifecycle::managing_a_canister_with_wrong_controller_fails
            ),
            t(
                "delete_stopped_canister_succeeds",
                execution::canister_lifecycle::delete_stopped_canister_succeeds
            ),
            t(
                "delete_running_canister_fails",
                execution::canister_lifecycle::delete_running_canister_fails
            ),
            t(
                "canister_can_manage_other_canister",
                execution::canister_lifecycle::canister_can_manage_other_canister
            ),
            t(
                "canister_can_manage_other_canister_batched",
                execution::canister_lifecycle::canister_can_manage_other_canister_batched
            ),
            t(
                "canister_large_wasm_small_memory_allocation",
                execution::canister_lifecycle::canister_large_wasm_small_memory_allocation
            ),
            t(
                "canister_large_initial_memory_small_memory_allocation",
                execution::canister_lifecycle::canister_large_initial_memory_small_memory_allocation
            ),
            t(
                "refunds_after_uninstall_are_refunded",
                execution::canister_lifecycle::refunds_after_uninstall_are_refunded
            ),
            t(
                "update_settings_with_controller_and_controllers_fails",
                execution::canister_lifecycle::update_settings_with_controller_and_controllers_fails
            ),
            t(
                "update_settings_multiple_controllers",
                execution::canister_lifecycle::update_settings_multiple_controllers
            ),
            t(
                "can_transfer_cycles_from_a_canister_to_another",
                execution::cycles_transfer::can_transfer_cycles_from_a_canister_to_another
            ),
            t(
                "trapping_with_large_blob_does_not_cause_cycles_underflow",
                execution::cycles_transfer::trapping_with_large_blob_does_not_cause_cycles_underflow
            ),
            t(
                "rejecting_with_large_blob_does_not_cause_cycles_underflow",
                execution::cycles_transfer::rejecting_with_large_blob_does_not_cause_cycles_underflow
            ),
            t(
                "canister_accepts_ingress_by_default",
                execution::ingress_rate_limiting::canister_accepts_ingress_by_default
            ),
            t(
                "empty_canister_inspect_rejects_all_messages",
                execution::ingress_rate_limiting::empty_canister_inspect_rejects_all_messages
            ),
            t(
                "canister_can_accept_ingress",
                execution::ingress_rate_limiting::canister_can_accept_ingress
            ),
            t(
                "canister_only_accepts_ingress_with_payload",
                execution::ingress_rate_limiting::canister_only_accepts_ingress_with_payload
            ),
            t(
                "canister_rejects_ingress_only_from_one_caller",
                execution::ingress_rate_limiting::canister_rejects_ingress_only_from_one_caller
            ),
            t(
                "query_reply_sizes",
                execution::queries::query_reply_sizes
            ),
            t(
                "mint_cycles_not_supported_on_system_subnet",
                execution::nns_shielding::mint_cycles_not_supported_on_system_subnet
            ),
            t(
                "mint_cycles_not_supported_on_application_subnet",
                execution::nns_shielding::mint_cycles_not_supported_on_application_subnet
            ),
            t(
                "no_cycle_balance_limit_on_nns_subnet",
                execution::nns_shielding::no_cycle_balance_limit_on_nns_subnet
            ),
            t(
                "app_canister_attempt_initiating_dkg_fails",
                execution::nns_shielding::app_canister_attempt_initiating_dkg_fails
            ),
            t(
                "canister_heartbeat_is_called_at_regular_intervals",
                execution::canister_heartbeat::canister_heartbeat_is_called_at_regular_intervals
            ),
            t(
                "stopping_a_canister_with_a_heartbeat_succeeds",
                execution::canister_heartbeat::stopping_a_canister_with_a_heartbeat_succeeds
            ),
            t(
                "canister_heartbeat_can_call_another_canister",
                execution::canister_heartbeat::canister_heartbeat_can_call_another_canister
            ),
            t(
                "canister_heartbeat_can_call_multiple_canisters_xnet",
                execution::canister_heartbeat::canister_heartbeat_can_call_multiple_canisters_xnet
            ),
            t(
                "canister_heartbeat_can_stop",
                execution::canister_heartbeat::canister_heartbeat_can_stop
            ),
            t(
                "canister_heartbeat_cannot_reply",
                execution::canister_heartbeat::canister_heartbeat_cannot_reply
            )
    ]),
    )
}

pub fn cycles_restrictions_pot() -> Pot {
    pot(
        "cycles_restriction_pot",
        execution::config_system_verified_application_subnets(),
        par(vec![
            t(
                "cannot_send_cycles_from_application_to_verified_subnets",
                execution::cycles_transfer::cannot_send_cycles_from_application_to_verified_subnets,
            ),
            t(
                "controller_and_controllee_on_different_subnets",
                execution::canister_lifecycle::controller_and_controllee_on_different_subnets,
            ),
            t(
                "can_use_more_instructions_during_install_code",
                execution::instructions_limit::can_use_more_instructions_during_install_code,
            ),
        ]),
    )
}

pub fn inter_canister_queries() -> Pot {
    pot(
        "inter_canister_queries",
        execution::config_system_verified_subnets(),
        par(vec![
            t(
                "intermediate_canister_does_not_reply",
                execution::inter_canister_queries::intermediate_canister_does_not_reply
            ),
            t(
                "cannot_query_xnet_canister",
                execution::inter_canister_queries::cannot_query_xnet_canister
            ),
            t(
                "simple_query",
                execution::inter_canister_queries::simple_query
            ),
            t(
                "self_loop_fails",
                execution::inter_canister_queries::self_loop_fails
            ),
            t(
                "canisters_loop_fails",
                execution::inter_canister_queries::canisters_loop_fails
            ),
            t(
                "query_two_canisters",
                execution::inter_canister_queries::query_two_canisters
            ),
            t(
                "query_three_canisters",
                execution::inter_canister_queries::query_three_canisters
            ),
            t(
                "canister_queries_non_existent",
                execution::inter_canister_queries::canister_queries_non_existent
            ),
            t(
                "canister_queries_does_not_reply",
                execution::inter_canister_queries::canister_queries_does_not_reply
            ),
            t(
                "inter_canister_query_first_canister_multiple_request",
                execution::inter_canister_queries::inter_canister_query_first_canister_multiple_request
            ),
            t(
                "is_called_if_reply_traps",
                execution::call_on_cleanup::is_called_if_reply_traps
            ),
            t(
                "is_called_if_reject_traps",
                execution::call_on_cleanup::is_called_if_reject_traps
            ),
            t(
                "changes_are_discarded_if_trapped",
                execution::call_on_cleanup::changes_are_discarded_if_trapped
            ),
            t(
                "changes_are_discarded_in_query",
                execution::call_on_cleanup::changes_are_discarded_in_query
            ),
            t(
                "is_called_in_query",
                execution::call_on_cleanup::is_called_in_query
            )
        ])
    )
}

pub fn compute_allocation_pot() -> Pot {
    pot(
        "compute_allocation_pot",
        execution::canister_lifecycle::config_compute_allocation(),
        par(vec![t(
            "total_compute_allocation_cannot_be_exceeded",
            execution::canister_lifecycle::total_compute_allocation_cannot_be_exceeded,
        )]),
    )
}
