{-
  This test contract serves two main purposes:
  1. It allows testing of non-getter functions in FunC without requiring specific opcodes for each function.
  2. It provides access to internal functions through wrapper getter functions.

  This approach is common in FunC development, where a separate test contract is used for unit testing.
  It enables more comprehensive testing of the contract's functionality, including internal operations
  that are not directly accessible through standard getter methods.
-}

#include "../imports/stdlib.fc";
#include "../Pyth.fc";
#include "../Wormhole.fc";
#include "../common/op.fc";

() recv_internal(int balance, int msg_value, cell in_msg_full, slice in_msg_body) impure {
    if (in_msg_body.slice_empty?()) {
        return ();
    }

    int op = in_msg_body~load_uint(32);
    cell data = in_msg_body~load_ref();
    slice data_slice = data.begin_parse();

    ;; Get sender address from message
    slice cs = in_msg_full.begin_parse();
    cs~skip_bits(4);  ;; skip flags
    slice sender_address = cs~load_msg_addr();  ;; load sender address

    if (op == OP_UPDATE_GUARDIAN_SET) {
        update_guardian_set(data_slice);
    } elseif (op == OP_UPDATE_PRICE_FEEDS) {
        update_price_feeds(msg_value, data_slice);
    } elseif (op == OP_EXECUTE_GOVERNANCE_ACTION) {
        execute_governance_action(data_slice);
    } elseif (op == OP_UPGRADE_CONTRACT) {
        execute_upgrade_contract(data);
    } elseif (op == OP_PARSE_PRICE_FEED_UPDATES) {
        cell price_ids_cell = in_msg_body~load_ref();
        slice price_ids_slice = price_ids_cell.begin_parse();
        int min_publish_time = in_msg_body~load_uint(64);
        int max_publish_time = in_msg_body~load_uint(64);
        slice target_address = in_msg_body~load_msg_addr();
        cell custom_payload_cell = in_msg_body~load_ref();
        slice custom_payload = custom_payload_cell.begin_parse();
        parse_price_feed_updates(msg_value, data_slice, price_ids_slice, min_publish_time, max_publish_time, sender_address, target_address, custom_payload);
    } elseif (op == OP_PARSE_UNIQUE_PRICE_FEED_UPDATES) {
        cell price_ids_cell = in_msg_body~load_ref();
        slice price_ids_slice = price_ids_cell.begin_parse();
        int publish_time = in_msg_body~load_uint(64);
        int max_staleness = in_msg_body~load_uint(64);
        slice target_address = in_msg_body~load_msg_addr();
        cell custom_payload_cell = in_msg_body~load_ref();
        slice custom_payload = custom_payload_cell.begin_parse();
        parse_unique_price_feed_updates(msg_value, data_slice, price_ids_slice, publish_time, max_staleness, sender_address, target_address, custom_payload);
    } else {
        throw(0xffff); ;; Throw exception for unknown op
    }
}

(int, int, int, int) test_get_price_unsafe(int price_feed_id) method_id {
    return get_price_unsafe(price_feed_id);
}

(int, int, int, int) test_get_price_no_older_than(int time_period, int price_feed_id) method_id {
    return get_price_no_older_than(time_period, price_feed_id);
}

(int, int, int, int) test_get_ema_price_unsafe(int price_feed_id) method_id {
    return get_ema_price_unsafe(price_feed_id);
}

(int, int, int, int) test_get_ema_price_no_older_than(int time_period, int price_feed_id) method_id {
    return get_ema_price_no_older_than(time_period, price_feed_id);
}

(int) test_get_update_fee(slice in_msg_body) method_id {
    return get_update_fee(in_msg_body);
}

(int) test_get_single_update_fee() method_id {
    return get_single_update_fee();
}

(int) test_get_chain_id() method_id {
    return get_chain_id();
}

(int) test_get_last_executed_governance_sequence() method_id {
    return get_last_executed_governance_sequence();
}

(int) test_get_governance_data_source_index() method_id {
    return get_governance_data_source_index();
}

(cell) test_get_governance_data_source() method_id {
    return get_governance_data_source();
}

(int) test_get_is_valid_data_source(cell data_source) method_id {
    return get_is_valid_data_source(data_source);
}
