#include "../imports/stdlib.fc";

;; Pyth
;; Price struct: {price: int, conf: int, expo: int, publish_time: int}
;; PriceFeed struct: {price: Price, ema_price: Price}
global cell latest_price_feeds; ;; Dictionary of PriceFeed structs, keyed by price_feed_id (256-bit)
global int single_update_fee;
;; DataSource struct: (emitter_chain_id: int, emitter_address: int)
;; emitter_chain_id is a 16-bit unsigned integer
;; emitter_address is a 256-bit unsigned integer
global cell is_valid_data_source; ;; Dictionary of int (0 as false, -1 as true), keyed by DataSource cell_hash
global int upgrade_code_hash; ;; 256-bit unsigned integer


;; Wormhole
global int current_guardian_set_index;
;; GuardianSet struct: {expiration_time: int, keys: cell}
;; The 'keys' cell is a dictionary with the following structure:
;; - Key: 8-bit unsigned integer (guardian index)
;; - Value: 160-bit unsigned integer (guardian address)
global cell guardian_sets;
global int chain_id;
global int governance_chain_id;
global int governance_contract;
global cell consumed_governance_actions; ;; Dictionary of int (0 as false, -1 as true), keyed by int (hash of the governance action)
global cell governance_data_source; ;; Single DataSource tuple
global int last_executed_governance_sequence; ;; u64
global int governance_data_source_index; ;; u32


() store_data() impure inline_ref {
    cell price_feeds_cell = begin_cell()
        .store_dict(latest_price_feeds)
        .store_uint(single_update_fee, 256)
        .end_cell();

    cell data_sources_cell = begin_cell()
        .store_dict(is_valid_data_source)
        .end_cell();

    cell guardian_set_cell = begin_cell()
        .store_uint(current_guardian_set_index, 32)
        .store_dict(guardian_sets)
        .end_cell();

    cell governance_cell = begin_cell()
        .store_uint(chain_id, 16)
        .store_uint(governance_chain_id, 16)
        .store_uint(governance_contract, 256)
        .store_dict(consumed_governance_actions)
        .store_ref(governance_data_source)
        .store_uint(last_executed_governance_sequence, 64)
        .store_uint(governance_data_source_index, 32)
        .store_uint(upgrade_code_hash, 256)
        .end_cell();

    begin_cell()
        .store_ref(price_feeds_cell)
        .store_ref(data_sources_cell)
        .store_ref(guardian_set_cell)
        .store_ref(governance_cell)
        .end_cell()
        .set_data();
}

;; load_data populates storage variables using stored data
() load_data() impure inline_ref {
    slice ds = get_data().begin_parse();

    cell price_feeds_cell = ds~load_ref();
    slice price_feeds_slice = price_feeds_cell.begin_parse();
    latest_price_feeds = price_feeds_slice~load_dict();
    single_update_fee = price_feeds_slice~load_uint(256);

    cell data_sources_cell = ds~load_ref();
    slice data_sources_slice = data_sources_cell.begin_parse();
    is_valid_data_source = data_sources_slice~load_dict();

    cell guardian_set_cell = ds~load_ref();
    slice guardian_set_slice = guardian_set_cell.begin_parse();
    current_guardian_set_index = guardian_set_slice~load_uint(32);
    guardian_sets = guardian_set_slice~load_dict();

    cell governance_cell = ds~load_ref();
    slice governance_slice = governance_cell.begin_parse();
    chain_id = governance_slice~load_uint(16);
    governance_chain_id = governance_slice~load_uint(16);
    governance_contract = governance_slice~load_uint(256);
    consumed_governance_actions = governance_slice~load_dict();
    governance_data_source = governance_slice~load_ref();
    last_executed_governance_sequence = governance_slice~load_uint(64);
    governance_data_source_index = governance_slice~load_uint(32);
    upgrade_code_hash = governance_slice~load_uint(256);

    ds.end_parse();
}
