1use std::{path::PathBuf, sync::Arc};
144
145use serde::{Deserialize, Serialize};
146use serde_json::json;
147use CommonLibrary::{
149 Configuration::{
150 ConfigurationProvider::ConfigurationProvider,
151 DTO::{
152 ConfigurationOverridesDTO as ConfigurationOverridesDTOModule,
153 ConfigurationTarget as ConfigurationTargetModule,
154 },
155 },
156 Environment::Requires::Requires,
157 Error::CommonError::CommonError,
158 FileSystem::{FileSystemReader::FileSystemReader, FileSystemWriter::FileSystemWriter},
159 Storage::StorageProvider::StorageProvider,
160};
161
162type ConfigurationOverridesDTO = ConfigurationOverridesDTOModule::ConfigurationOverridesDTO;
164type ConfigurationTarget = ConfigurationTargetModule::ConfigurationTarget;
165
166use crate::{RunTime::ApplicationRunTime::ApplicationRunTime, dev_log};
167
168#[derive(Debug, Clone, Serialize, Deserialize)]
171pub struct WindDesktopConfiguration {
172 pub window_id:u32,
173 pub app_root:String,
174 pub user_data_path:String,
175 pub temp_path:String,
176 pub log_level:String,
177 pub is_packaged:bool,
178 pub tauri_version:String,
179 pub platform:String,
180 pub arch:String,
181 pub workspace:Option<serde_json::Value>,
182 pub files_to_open_or_create:Option<Vec<FileToOpenOrCreate>>,
183 pub files_to_diff:Option<Vec<FileToDiff>>,
184 pub files_to_wait:Option<FilesToWait>,
185 pub fullscreen:Option<bool>,
186 pub zoom_level:Option<f64>,
187 pub is_custom_zoom_level:Option<bool>,
188 pub profiles:Profiles,
189 pub policies_data:Option<serde_json::Value>,
190 pub loggers:Vec<Logger>,
191 pub backup_path:Option<String>,
192 pub disable_layout_restore:Option<bool>,
193 pub os:OsInfo,
194}
195
196#[derive(Debug, Clone, Serialize, Deserialize)]
198pub struct FileToOpenOrCreate {
199 pub file_uri:String,
200}
201
202#[derive(Debug, Clone, Serialize, Deserialize)]
204pub struct FileToDiff {
205 pub file_uri:String,
206}
207
208#[derive(Debug, Clone, Serialize, Deserialize)]
210pub struct FilesToWait {
211 pub wait_marker_file_uri:String,
212 pub paths:Vec<FileToOpenOrCreate>,
213}
214
215#[derive(Debug, Clone, Serialize, Deserialize)]
217pub struct Profiles {
218 pub all:Vec<serde_json::Value>,
219 pub home:String,
220 pub profile:serde_json::Value,
221}
222
223#[derive(Debug, Clone, Serialize, Deserialize)]
225pub struct Logger {
226 pub resource:serde_json::Value,
227}
228
229#[derive(Debug, Clone, Serialize, Deserialize)]
231pub struct OsInfo {
232 pub release:String,
233}
234
235pub struct WindServiceAdapter {
237 runtime:Arc<ApplicationRunTime>,
238}
239
240impl WindServiceAdapter {
241 pub fn new(runtime:Arc<ApplicationRunTime>) -> Self {
243 dev_log!("ipc", "[WindServiceAdapters] Creating Wind service adapter");
244 Self { runtime }
245 }
246
247 pub async fn convert_to_wind_configuration(
249 &self,
250 mountain_config:serde_json::Value,
251 ) -> Result<WindDesktopConfiguration, String> {
252 dev_log!("ipc", "[WindServiceAdapters] Converting Mountain config to Wind config");
253
254 let config:MountainSandboxConfiguration = serde_json::from_value(mountain_config)
256 .map_err(|e| format!("Failed to parse Mountain configuration: {}", e))?;
257
258 let wind_config = WindDesktopConfiguration {
260 window_id:config.window_id.parse().unwrap_or(1),
261 app_root:config.app_root,
262 user_data_path:config.user_data_dir,
263 temp_path:config.tmp_dir,
264 log_level:config.log_level.to_string(),
265 is_packaged:config.product_configuration.is_packaged,
266 tauri_version:config.versions.mountain,
267 platform:config.platform,
268 arch:config.arch,
269 workspace:None,
270 files_to_open_or_create:None,
271 files_to_diff:None,
272 files_to_wait:None,
273 fullscreen:Some(false),
274 zoom_level:Some(config.zoom_level),
275 is_custom_zoom_level:Some(false),
276 profiles:Profiles { all:vec![], home:config.home_dir, profile:serde_json::Value::Null },
277 policies_data:None,
278 loggers:vec![],
279 backup_path:Some(config.backup_path),
280 disable_layout_restore:Some(false),
281 os:OsInfo { release:std::env::consts::OS.to_string() },
282 };
283
284 Ok(wind_config)
285 }
286
287 pub async fn get_environment_service(&self) -> Result<WindEnvironmentService, String> {
289 dev_log!("ipc", "[WindServiceAdapters] Getting Wind environment service");
290
291 Ok(WindEnvironmentService::new())
292 }
293
294 pub async fn get_file_service(&self) -> Result<WindFileService, String> {
296 dev_log!("ipc", "[WindServiceAdapters] Getting Wind file service");
297
298 let file_system_reader:Arc<dyn FileSystemReader> = self.runtime.Environment.Require();
299
300 let file_system_writer:Arc<dyn FileSystemWriter> = self.runtime.Environment.Require();
301
302 Ok(WindFileService::new(file_system_reader, file_system_writer))
303 }
304
305 pub async fn get_storage_service(&self) -> Result<WindStorageService, String> {
307 dev_log!("ipc", "[WindServiceAdapters] Getting Wind storage service");
308
309 let storage:Arc<dyn StorageProvider> = self.runtime.Environment.Require();
310
311 Ok(WindStorageService::new(storage))
312 }
313
314 pub async fn get_configuration_service(&self) -> Result<WindConfigurationService, String> {
316 dev_log!("ipc", "[WindServiceAdapters] Getting Wind configuration service");
317
318 let config:Arc<dyn ConfigurationProvider> = self.runtime.Environment.Require();
319
320 Ok(WindConfigurationService::new(config))
321 }
322}
323
324pub struct WindEnvironmentService {
326 }
328
329impl WindEnvironmentService {
330 pub fn new() -> Self { Self {} }
331
332 pub async fn get_app_root(&self) -> Result<String, String> { std::env::var("APP_ROOT").map_err(|e| e.to_string()) }
333
334 pub async fn get_user_data_path(&self) -> Result<String, String> {
335 std::env::var("USER_DATA_PATH").map_err(|e| e.to_string())
336 }
337}
338
339pub struct WindFileService {
341 reader:Arc<dyn FileSystemReader>,
342 writer:Arc<dyn FileSystemWriter>,
343}
344
345impl WindFileService {
346 pub fn new(reader:Arc<dyn FileSystemReader>, writer:Arc<dyn FileSystemWriter>) -> Self { Self { reader, writer } }
347
348 pub async fn read_file(&self, path:String) -> Result<Vec<u8>, String> {
349 self.reader.ReadFile(&PathBuf::from(path)).await.map_err(|e| e.to_string())
350 }
351
352 pub async fn write_file(&self, path:String, content:Vec<u8>) -> Result<(), String> {
353 self.writer
354 .WriteFile(&PathBuf::from(path), content, true, true)
355 .await
356 .map_err(|e:CommonError| e.to_string())
357 }
358
359 pub async fn stat_file(&self, path:String) -> Result<serde_json::Value, String> {
360 let stat_dto = self
361 .reader
362 .StatFile(&PathBuf::from(path))
363 .await
364 .map_err(|e:CommonError| e.to_string())?;
365 Ok(json!(stat_dto))
366 }
367}
368
369pub struct WindStorageService {
371 provider:Arc<dyn StorageProvider>,
372}
373
374impl WindStorageService {
375 pub fn new(provider:Arc<dyn StorageProvider>) -> Self { Self { provider } }
376
377 pub async fn get(&self, key:String) -> Result<serde_json::Value, String> {
378 let value = self
379 .provider
380 .GetStorageValue(false, &key)
381 .await
382 .map_err(|e:CommonError| e.to_string())?
383 .ok_or_else(|| "Storage key not found".to_string())?;
384 Ok(value)
385 }
386
387 pub async fn set(&self, key:String, value:serde_json::Value) -> Result<(), String> {
388 self.provider
389 .UpdateStorageValue(false, key.to_string(), Some(value))
390 .await
391 .map_err(|e:CommonError| e.to_string())
392 }
393}
394
395pub struct WindConfigurationService {
397 provider:Arc<dyn ConfigurationProvider>,
398}
399
400impl WindConfigurationService {
401 pub fn new(provider:Arc<dyn ConfigurationProvider>) -> Self { Self { provider } }
402
403 pub async fn get_value(&self, key:String) -> Result<serde_json::Value, String> {
404 self.provider
405 .GetConfigurationValue(Some(key.to_string()), ConfigurationOverridesDTO::default())
406 .await
407 .map_err(|e| e.to_string())
408 }
409
410 pub async fn update_value(&self, key:String, value:serde_json::Value) -> Result<(), String> {
411 self.provider
412 .UpdateConfigurationValue(
413 key,
414 value,
415 ConfigurationTarget::User,
416 ConfigurationOverridesDTO::default(),
417 None,
418 )
419 .await
420 .map_err(|e| e.to_string())
421 }
422}
423
424#[derive(Debug, Clone, Serialize, Deserialize)]
426struct MountainSandboxConfiguration {
427 pub window_id:String,
428 pub machine_id:String,
429 pub session_id:String,
430 pub log_level:i32,
431 pub user_env:std::collections::HashMap<String, String>,
432 pub app_root:String,
433 pub app_name:String,
434 pub app_uri_scheme:String,
435 pub app_language:String,
436 pub app_host:String,
437 pub platform:String,
438 pub arch:String,
439 pub versions:Versions,
440 pub exec_path:String,
441 pub home_dir:String,
442 pub tmp_dir:String,
443 pub user_data_dir:String,
444 pub backup_path:String,
445 pub resources_path:String,
446 pub vscode_cwd:String,
447 pub nls:NLSConfiguration,
448 pub product_configuration:ProductConfiguration,
449 pub zoom_level:f64,
450}
451
452#[derive(Debug, Clone, Serialize, Deserialize)]
453struct Versions {
454 pub mountain:String,
455 pub electron:String,
456 pub chrome:String,
457 pub node:String,
458}
459
460#[derive(Debug, Clone, Serialize, Deserialize)]
461struct NLSConfiguration {
462 pub messages:std::collections::HashMap<String, String>,
463 pub language:String,
464 pub available_languages:std::collections::HashMap<String, String>,
465}
466
467#[derive(Debug, Clone, Serialize, Deserialize)]
468struct ProductConfiguration {
469 pub name_short:String,
470 pub name_long:String,
471 pub application_name:String,
472 pub embedder_identifier:String,
473 pub is_packaged:bool,
474}