use anyhow::Result;
use wasmtime::component::{Component, Linker};
use wasmtime::{Config, Engine};
use crate::store::HostState;
use crate::{credentials, fs_policy};
pub fn create_engine() -> Result<Engine> {
let mut config = Config::new();
config.wasm_component_model(true);
config.wasm_component_model_async(true);
config.wasm_exceptions(true);
config.wasm_function_references(true);
config.wasm_gc(true);
let engine = Engine::new(&config)
.map_err(|e| anyhow::anyhow!("failed to create wasmtime engine: {e}"))?;
Ok(engine)
}
pub fn load_component(engine: &Engine, path: &std::path::Path) -> Result<(Component, String)> {
let bytes = std::fs::read(path)
.map_err(|e| anyhow::anyhow!("failed to read component {}: {e}", path.display()))?;
let digest = crate::audit::sha256_hex(&bytes);
let component = Component::from_binary(engine, &bytes)
.map_err(|e| anyhow::anyhow!("failed to load component from {}: {e}", path.display()))?;
Ok((component, digest))
}
pub fn create_linker(engine: &Engine) -> Result<Linker<HostState>> {
let mut linker = Linker::new(engine);
wasmtime_wasi::p2::add_to_linker_async(&mut linker)
.map_err(|e| anyhow::anyhow!("failed to add WASI P2 to linker: {e}"))?;
linker.allow_shadowing(true);
wasmtime_wasi::p2::bindings::filesystem::types::add_to_linker::<
HostState,
fs_policy::PolicyFilesystem,
>(&mut linker, super::store::HostState::policy_fs_view)
.map_err(|e| anyhow::anyhow!("failed to add policy wasi:filesystem/types: {e}"))?;
wasmtime_wasi::p2::bindings::filesystem::preopens::add_to_linker::<
HostState,
fs_policy::PolicyFilesystem,
>(&mut linker, super::store::HostState::policy_fs_view)
.map_err(|e| anyhow::anyhow!("failed to add policy wasi:filesystem/preopens: {e}"))?;
linker.allow_shadowing(false);
wasmtime_wasi::p3::add_to_linker(&mut linker)
.map_err(|e| anyhow::anyhow!("failed to add WASI P3 to linker: {e}"))?;
linker.allow_shadowing(true);
wasmtime_wasi::p3::bindings::filesystem::preopens::add_to_linker::<
HostState,
fs_policy::PolicyFilesystem,
>(&mut linker, super::store::HostState::policy_fs_view)
.map_err(|e| anyhow::anyhow!("failed to add policy wasi:filesystem/preopens (p3): {e}"))?;
linker.allow_shadowing(false);
wasmtime_wasi_http::p2::add_only_http_to_linker_async(&mut linker)
.map_err(|e| anyhow::anyhow!("failed to add WASI HTTP P2 to linker: {e}"))?;
wasmtime_wasi_http::p3::add_to_linker(&mut linker)
.map_err(|e| anyhow::anyhow!("failed to add WASI HTTP P3 to linker: {e}"))?;
credentials::add_to_linker(&mut linker)?;
crate::consent::gate::add_to_linker(&mut linker)?;
Ok(linker)
}