You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: init_globals.rs
    path of file: ./repos/holochain-rust/crates/core/src/wasm_engine/api
    
    the code of the file until where you have to start completion: use crate::wasm_engine::{api::ZomeApiResult, Runtime};
use holochain_core_types::entry::entry_type::EntryType;

use holochain_persistence_api::{
    cas::content::{Address, AddressableContent},
    hash::HashString,
};

use holochain_json_api::json::JsonString;

use holochain_wasm_utils::api_serialization::ZomeApiGlobals;
use wasmi::RuntimeArgs;

/// ZomeApiFunction::InitGlobals secret function code
/// args: [0] encoded MemoryAllocation as u64
/// Not expecting any complex input
/// Returns an HcApiReturnCode as I64
#[holochain_tracing_macros::newrelic_autotrace(HOLOCHAIN_CORE)]
pub fn invoke_init_globals(runtime: &mut Runtime, _args: &RuntimeArgs) -> ZomeApiResult {
    let call_data = runtime.call_data()?;
    let dna = runtime
        .context()?
        .get_dna()
        .expect("No DNA found in invoke_init_globals");
    let dna_name = dna.name.clone();
    // Create the ZomeApiGlobals struct with some default values
    let mut globals = ZomeApiGlobals {
      
    
pub fn invoke_init_globals(runtime: &mut Runtime, _args: &RuntimeArgs) -> ZomeApiResult {
    let call_data = runtime.call_data()?;
    let dna = runtime
        .context()?
        .get_dna()
        .expect("No DNA found in invoke_init_globals");
    let dna_name = dna.name.clone();
    // Create the ZomeApiGlobals struct with some default values
    let mut globals = ZomeApiGlobals {
        dna_name,
        dna_address: Address::from(""),
        agent_id_str: JsonString::from(call_data.context.agent_id.clone()).to_string(),
        agent_address: call_data.context.agent_id.address(),
        agent_initial_hash: HashString::from(""),
        agent_latest_hash: HashString::from(""),
        public_token: Address::from(""),
        cap_request: runtime
            .zome_call_data()
            .map(|zome_call_data| Some(zome_call_data.call.cap))
            .unwrap_or_else(|_| None),
        properties: JsonString::from(dna.properties),
    };

    // Update fields
    if let Some(state) = call_data.context.state() {
        // Update dna_address
        if let Some(dna) = state.nucleus().dna() {
            globals.dna_address = dna.address()
        }
        // Update agent hashes
        let maybe_top = state.agent().top_chain_header();
        if maybe_top.is_some() {
            let mut found_entries: Vec<Address> = vec![];
            for chain_header in state
                .agent()
                .chain_store()
                .iter_type(&maybe_top, &EntryType::AgentId)
            {
                found_entries.push(chain_header.entry_address().to_owned());
            }
            if !found_entries.is_empty() {
                globals.agent_latest_hash = found_entries[0].clone();
                globals.agent_initial_hash = found_entries.pop().unwrap();
                globals.agent_address = globals.agent_latest_hash.clone();
            }
        }
    };

    // Update public_token
    let maybe_token = call_data.context.get_public_token();
    if let Ok(token) = maybe_token {
        globals.public_token = token;
    }

    // Store it in wasm memory
    runtime.store_result(Ok(globals))
}