use crate::functions;
use anyhow::{Result, anyhow};
use mlua::{self, Lua, LuaSerdeExt, Table, Value};
use std::fs;
use zoi_core::{types, utils};
pub fn parse_lua_package_for_platform(
file_path: &str,
platform: &str,
version_override: Option<&str>,
quiet: bool,
) -> Result<types::Package> {
let lua_code = fs::read_to_string(file_path)?;
let lua = Lua::new();
let pkg_meta_table = lua.create_table().map_err(|e| anyhow!(e.to_string()))?;
let pkg_deps_table = lua.create_table().map_err(|e| anyhow!(e.to_string()))?;
let pkg_updates_table = lua.create_table().map_err(|e| anyhow!(e.to_string()))?;
let pkg_hooks_table = lua.create_table().map_err(|e| anyhow!(e.to_string()))?;
let pkg_service_table = lua.create_table().map_err(|e| anyhow!(e.to_string()))?;
lua.globals()
.set("__ZoiPackageMeta", pkg_meta_table)
.map_err(|e| anyhow!(e.to_string()))?;
lua.globals()
.set("__ZoiPackageDeps", pkg_deps_table)
.map_err(|e| anyhow!(e.to_string()))?;
lua.globals()
.set("__ZoiPackageUpdates", pkg_updates_table)
.map_err(|e| anyhow!(e.to_string()))?;
lua.globals()
.set("__ZoiPackageHooks", pkg_hooks_table)
.map_err(|e| anyhow!(e.to_string()))?;
lua.globals()
.set("__ZoiPackageService", pkg_service_table)
.map_err(|e| anyhow!(e.to_string()))?;
let pkg_table = lua.create_table().map_err(|e| anyhow!(e.to_string()))?;
lua.globals()
.set("PKG", pkg_table)
.map_err(|e| anyhow!(e.to_string()))?;
functions::setup_lua_environment(
&lua,
platform,
version_override,
Some(file_path),
None,
None,
None,
None,
quiet,
)
.map_err(|e| anyhow!("Failed to setup Lua environment for '{}': {}", file_path, e))?;
lua.load(&lua_code).exec().map_err(|e| {
anyhow!(
"Failed to execute Lua package file '{}':
{}",
file_path,
e
)
})?;
let final_pkg_meta: Table = lua
.globals()
.get("__ZoiPackageMeta")
.map_err(|e| anyhow!(e.to_string()))?;
let final_pkg_deps: Table = lua
.globals()
.get("__ZoiPackageDeps")
.map_err(|e| anyhow!(e.to_string()))?;
let final_pkg_updates: Table = lua
.globals()
.get("__ZoiPackageUpdates")
.map_err(|e| anyhow!(e.to_string()))?;
let final_pkg_hooks: Table = lua
.globals()
.get("__ZoiPackageHooks")
.map_err(|e| anyhow!(e.to_string()))?;
let final_pkg_service: Table = lua
.globals()
.get("__ZoiPackageService")
.map_err(|e| anyhow!(e.to_string()))?;
let mut package: types::Package =
lua.from_value(Value::Table(final_pkg_meta)).map_err(|e| {
anyhow!(
"Failed to parse 'metadata' block in package file '{}':
{}",
file_path,
e
)
})?;
package.dependencies = if final_pkg_deps.is_empty() {
None
} else {
Some(lua.from_value(Value::Table(final_pkg_deps)).map_err(|e| {
anyhow!(
"Failed to parse 'dependencies' block in package file '{}':
{}",
file_path,
e
)
})?)
};
package.updates = if final_pkg_updates.is_empty() {
None
} else {
Some(
lua.from_value(Value::Table(final_pkg_updates))
.map_err(|e| {
anyhow!(
"Failed to parse 'updates' block in package file '{}':
{}",
file_path,
e
)
})?,
)
};
package.hooks = if final_pkg_hooks.is_empty() {
None
} else {
Some(lua.from_value(Value::Table(final_pkg_hooks)).map_err(|e| {
anyhow!(
"Failed to parse 'hooks' block in package file '{}':
{}",
file_path,
e
)
})?)
};
package.service = if final_pkg_service.is_empty() {
None
} else {
Some(
lua.from_value(Value::Table(final_pkg_service))
.map_err(|e| {
anyhow!(
"Failed to parse 'service' block in package file '{}':
{}",
file_path,
e
)
})?,
)
};
Ok(package)
}
pub fn parse_lua_package(
file_path: &str,
version_override: Option<&str>,
quiet: bool,
) -> Result<types::Package> {
let platform = utils::get_platform()?;
parse_lua_package_for_platform(file_path, &platform, version_override, quiet)
}