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