#![allow(clippy::doc_markdown)]
use crate::Error;
use crate::dir_context::PathResolver;
use crate::hub::get_hub;
use crate::runtime::Runtime;
use crate::script::aip_modules::support::check_access_write;
use crate::support::text;
use crate::types::{ChangesInfo, FileInfo};
use mlua::{IntoLua, Lua, Value};
use simple_fs::{SPath, ensure_file_dir};
use std::fs::write;
pub(super) fn file_save_changes(
lua: &Lua,
runtime: &Runtime,
rel_path: String,
changes: String,
) -> mlua::Result<(Value, Value)> {
let dir_context = runtime.dir_context();
let full_path = dir_context.resolve_path(runtime.session(), (&rel_path).into(), PathResolver::WksDir, None)?;
let lock_handle = runtime.file_write_manager().lock_for_path(&full_path);
let _guard = lock_handle.lock();
let wks_dir = dir_context.try_wks_dir_with_err_ctx("aip.file.save requires a aipack workspace setup")?;
check_access_write(&full_path, wks_dir)?;
ensure_file_dir(&full_path).map_err(Error::from)?;
let (content, apply_changes_info) = if full_path.exists() {
let content = simple_fs::read_to_string(&full_path).map_err(Error::custom)?;
text::apply_changes(content, changes)?
} else {
(
changes,
ChangesInfo {
changed_count: 1,
failed_changes: Vec::new(),
},
)
};
write(&full_path, content).map_err(|err| Error::custom(format!("Fail to save file {rel_path}.\nCause {err}")))?;
let rel_path_for_hub = full_path.diff(wks_dir).unwrap_or_else(|| full_path.clone());
get_hub().publish_sync(format!("-> Lua aip.file.save called on: {rel_path_for_hub}"));
let file_info = FileInfo::new(runtime.dir_context(), SPath::new(rel_path), &full_path);
Ok((file_info.into_lua(lua)?, apply_changes_info.into_lua(lua)?))
}