pispas_service\service/
server.rs

1pub mod pispas_server {
2    use std::net::{TcpListener, TcpStream};
3    use std::io::{Write};
4    #[cfg(not(target_os = "windows"))]
5
6    use {
7        users::{get_user_by_uid},
8        users::os::unix::UserExt,
9        nix::sys::signal::{self, Signal},
10        nix::unistd::Pid,
11    };
12
13
14
15    const DEFAULT_CICLES_TO_WAIT_IN_MS: u64 = 500;
16    use anyhow::anyhow;
17    use std::collections::HashMap;
18    use std::thread;
19    use easy_trace::instruments::tracing::{error, info, warn};
20    use easy_trace::prelude::debug;
21    use parking_lot::RwLock;
22    use sharing::service::{Action, DriverStatus};
23    use std::io::Read;
24
25    use std::sync::atomic::{AtomicBool, Ordering};
26    use std::sync::Arc;
27    use std::thread::sleep;
28    use std::time::Duration;
29    #[cfg(target_os = "windows")]
30    use {
31        std::os::windows::ffi::OsStrExt,
32        winapi::um::{
33            errhandlingapi::GetLastError,
34            fileapi::CreateFileW,
35            handleapi::CloseHandle,
36            handleapi::DuplicateHandle,
37            minwinbase::STILL_ACTIVE,
38            processthreadsapi::GetCurrentProcess,
39            processthreadsapi::{GetExitCodeProcess, TerminateProcess},
40            winnt::{DUPLICATE_SAME_ACCESS, HANDLE},
41            winnt::{FILE_SHARE_READ, FILE_SHARE_WRITE},
42            winnt::{GENERIC_READ, GENERIC_WRITE},
43        }
44    };
45
46
47    pub type CancelToken = Arc<AtomicBool>;// Cambiar la estructura HandlePair para ser multiplataforma
48    #[derive(Debug)]
49    pub struct HandlePair {
50        #[cfg(windows)]
51        pub original: HANDLE,           // El que mantiene el service para protección
52        #[cfg(windows)]
53        pub duplicated: Option<HANDLE>, // El que se envía al módulo
54
55        #[cfg(unix)]
56        pub _original: std::fs::File,    // El que mantiene el service para protección
57        #[cfg(unix)]
58        pub duplicated: Option<i32>,    // File descriptor que se envía al módulo
59
60        #[cfg(unix)]
61        pub file_path: String,          // Path del archivo para Unix
62    }
63
64
65    #[derive(Debug, Clone)]
66    pub struct MyHandler {
67        #[cfg(windows)]
68        pub handle: HANDLE,
69        #[cfg(unix)]
70        pub pid: u32,
71        #[cfg(unix)]
72        process_dead: Arc<std::sync::atomic::AtomicBool>,
73    }
74    unsafe impl Send for MyHandler {}
75
76    unsafe impl Sync for MyHandler {}
77    #[cfg(unix)]
78    impl MyHandler {
79        pub fn new(pid: u32) -> Self {
80            Self {
81                pid,
82                process_dead: Arc::new(AtomicBool::new(false)),
83            }
84        }
85
86        pub fn _get_pid(&self) -> u32 {
87            self.pid
88        }
89
90        pub fn try_wait(&self) -> sharing::PisPasResult<Option<i32>> {
91            if self.process_dead.load(Ordering::Relaxed) {
92                return Ok(Some(0));
93            }
94
95            let pid = Pid::from_raw(self.pid as i32);
96
97            match signal::kill(pid, None) {
98                Ok(_) => {
99                    // Proceso existe y está vivo
100                    Ok(None)
101                }
102                Err(nix::errno::Errno::ESRCH) => {
103                    // Proceso no existe (terminó)
104                    self.process_dead.store(true, Ordering::Relaxed);
105                    tracing::info!("Process {} has terminated", self.pid);
106                    Ok(Some(0))
107                }
108                Err(e) => {
109                    // Otro error (EPERM, etc.) - asumir que sigue vivo
110                    tracing::warn!("Error checking process {}: {} - assuming alive", self.pid, e);
111                    Ok(None)
112                }
113            }
114        }
115
116        pub fn kill(&self) -> sharing::PisPasResult<()> {
117            let pid = Pid::from_raw(self.pid as i32);
118
119            // Verificar si el proceso existe primero
120            match signal::kill(pid, None) {
121                Ok(_) => {
122                    // El proceso existe, intentar terminarlo gracefully con SIGTERM
123                    match signal::kill(pid, Signal::SIGTERM) {
124                        Ok(_) => {
125                            tracing::info!("Sent SIGTERM to process {}", self.pid);
126                            std::thread::sleep(Duration::from_millis(1000));
127
128                            // Verificar si terminó
129                            match signal::kill(pid, None) {
130                                Ok(_) => {
131                                    // Aún vivo, usar SIGKILL (forzado)
132                                    match signal::kill(pid, Signal::SIGKILL) {
133                                        Ok(_) => {
134                                            tracing::info!("Sent SIGKILL to process {}", self.pid);
135                                            self.process_dead.store(true, Ordering::Relaxed);
136                                            Ok(())
137                                        }
138                                        Err(e) => {
139                                            tracing::error!("Failed to kill process {}: {}", self.pid, e);
140                                            Err(anyhow!("Failed to kill process {}: {}", self.pid, e))
141                                        }
142                                    }
143                                }
144                                Err(_) => {
145                                    // Proceso terminado exitosamente con SIGTERM
146                                    tracing::info!("Process {} terminated gracefully with SIGTERM", self.pid);
147                                    self.process_dead.store(true, Ordering::Relaxed);
148                                    Ok(())
149                                }
150                            }
151                        }
152                        Err(e) => {
153                            tracing::error!("Failed to send SIGTERM to process {}: {}", self.pid, e);
154                            Err(anyhow!("Failed to send SIGTERM to process {}: {}", self.pid, e))
155                        }
156                    }
157                }
158                Err(nix::errno::Errno::ESRCH) => {
159                    // El proceso no existe (ya está muerto)
160                    tracing::info!("Process {} not found (already dead)", self.pid);
161                    self.process_dead.store(true, Ordering::Relaxed);
162                    Ok(())
163                }
164                Err(e) => {
165                    tracing::error!("Error accessing process {}: {}", self.pid, e);
166                    Err(anyhow!("Error accessing process {}: {}", self.pid, e))
167                }
168            }
169        }
170
171        pub fn _is_alive(&self) -> sharing::PisPasResult<bool> {
172            if self.process_dead.load(Ordering::Relaxed) {
173                return Ok(false);
174            }
175
176            let pid = Pid::from_raw(self.pid as i32);
177            info!("Trying to kill pid {}", self.pid);
178            match signal::kill(pid, None) {
179                Ok(_) => Ok(true),
180                Err(nix::errno::Errno::ESRCH) => {
181                    self.process_dead.store(true, Ordering::Relaxed);
182                    Ok(false)
183                }
184                Err(e) => {
185                    tracing::warn!("Error checking if process {} is alive: {}", self.pid, e);
186                    // En caso de duda, asumir que está vivo
187                    Ok(true)
188                }
189            }
190        }
191    }
192    #[cfg(windows)]
193    impl MyHandler {
194        pub fn new(handle: HANDLE) -> Self {
195            Self { handle }
196        }
197        pub fn get_handle(&self) -> HANDLE {
198            self.handle
199        }
200    }
201    impl Clone for HandlePair {
202        fn clone(&self) -> Self {
203            #[cfg(windows)]
204            {
205                Self {
206                    original: self.original,
207                    duplicated: self.duplicated,
208                }
209            }
210
211            #[cfg(unix)]
212            {
213                // En Unix, no podemos clonar File directamente
214                // Crear un File dummy que apunte al mismo path
215                match std::fs::File::open(&self.file_path) {
216                    Ok(file) => Self {
217                        _original: file,
218                        duplicated: self.duplicated,
219                        file_path: self.file_path.clone(),
220                    },
221                    Err(_) => {
222                        // Si falla, crear un archivo temporal
223                        let temp_file = std::fs::File::create("/tmp/pispas_clone_dummy")
224                            .unwrap_or_else(|_| panic!("Failed to create dummy file"));
225                        Self {
226                            _original: temp_file,
227                            duplicated: self.duplicated,
228                            file_path: self.file_path.clone(),
229                        }
230                    }
231                }
232            }
233        }
234    }
235
236    // 3. AÑADIR imports para sysinfo:
237
238    unsafe impl Send for HandlePair {}
239    unsafe impl Sync for HandlePair {}
240
241    impl HandlePair {
242        #[cfg(windows)]
243        pub fn new(original: HANDLE, duplicated: Option<HANDLE>) -> Self {
244            Self {
245                original,
246                duplicated,
247            }
248        }
249
250        #[cfg(unix)]
251        pub fn new_unix(original: std::fs::File, file_path: String) -> Self {
252            Self {
253                _original: original,
254                duplicated: None,
255                file_path,
256            }
257        }
258
259        #[cfg(windows)]
260        pub fn _get_handle(&self) -> HANDLE {
261            self.original
262        }
263
264
265        #[cfg(windows)]
266        pub fn get_duplicated(&self) -> HANDLE {
267            self.duplicated.unwrap_or(std::ptr::null_mut())
268        }
269
270        #[cfg(unix)]
271        pub fn get_duplicated(&self) -> i32 {
272            self.duplicated.unwrap_or(-1)
273        }
274
275        #[cfg(windows)]
276        pub fn has_original(&self) -> bool {
277            !self.original.is_null()
278        }
279
280        #[cfg(unix)]
281        pub fn has_original(&self) -> bool {
282            true // En Unix, si el File existe, es válido
283        }
284
285        #[cfg(windows)]
286        pub fn is_valid(&self) -> bool {
287            !self.original.is_null()
288                && self.duplicated.is_some()
289                && self.get_duplicated() != std::ptr::null_mut()
290        }
291
292        #[cfg(unix)]
293        pub fn is_valid(&self) -> bool {
294            self.duplicated.is_some() && self.get_duplicated() != -1
295        }
296
297        #[cfg(windows)]
298        pub fn close_all(&self) {
299            unsafe {
300                if !self.original.is_null() {
301                    CloseHandle(self.original);
302                }
303                if let Some(dup_handle) = self.duplicated {
304                    if dup_handle != std::ptr::null_mut() {
305                        CloseHandle(dup_handle);
306                    }
307                }
308            }
309        }
310
311        pub fn close_duplicated(&self) {
312            #[cfg(windows)]
313            {
314                if let Some(dup_handle) = self.duplicated {
315                    if dup_handle != std::ptr::null_mut() {
316                        unsafe {
317                            CloseHandle(dup_handle);
318                        }
319                    }
320                }
321            }
322
323            #[cfg(unix)]
324            {
325                // En Unix, cerramos el fd duplicado si existe
326                if let Some(fd) = self.duplicated {
327                    if fd != -1 {
328                        unsafe {
329                            libc::close(fd);
330                        }
331                    }
332                }
333            }
334        }
335
336
337        // #[cfg(unix)]
338        // pub fn close_original(&self) {
339        //     // En Unix, el File se cierra automáticamente cuando se hace drop
340        //     // No hacemos nada aquí
341        // }
342
343        #[cfg(unix)]
344        pub fn close_all(&self) {
345            // En Unix, el File se cierra automáticamente cuando se hace drop
346            // Solo cerramos el fd duplicado si existe
347            if let Some(fd) = self.duplicated {
348                if fd != -1 {
349                    unsafe {
350                        libc::close(fd);
351                    }
352                }
353            }
354        }
355    }
356
357    #[derive(Debug)]
358    pub struct Server {
359        process: Option<MyHandler>,
360        tray_status: Arc<RwLock<DriverStatus>>,
361        subcribe_vector: Vec<Arc<RwLock<TcpStream>>>,
362        started: bool,
363        last_status_send: Arc<RwLock<String>>,
364        map_files: Arc<RwLock<HashMap<String, Option<HandlePair>>>>,
365    }
366
367    impl Server {
368        pub fn new() -> Self {
369            Self {
370                process: None,
371                tray_status: Arc::new(RwLock::new(DriverStatus::Launched)),
372                subcribe_vector: Vec::new(),
373                started: false,
374                last_status_send: Arc::new(RwLock::new(String::new())),
375                map_files: Arc::new(RwLock::new(HashMap::new())),
376            }
377        }
378
379        #[cfg(unix)]
380        fn create_or_open_protected_file(
381            &mut self,
382            file_path: &str,
383        ) -> sharing::PisPasResult<(std::fs::File, i32)> {
384            use std::fs::OpenOptions;
385            use std::os::unix::io::{AsRawFd};
386
387            info!("Creating/opening protected file (Unix): {}", file_path);
388
389            // Crear el directorio si no existe
390            if let Some(parent) = std::path::Path::new(file_path).parent() {
391                std::fs::create_dir_all(parent)
392                    .map_err(|e| anyhow!("Failed to create directory: {}", e))?;
393            }
394            
395            if let Err(e) = self.verify_and_restore_from_backup(file_path) {
396                warn!("Failed to verify/restore backup for {}: {}", file_path, e);
397            }
398
399
400            // Abrir el archivo con permisos de lectura/escritura
401            let original_file = OpenOptions::new()
402                .create(true)
403                .read(true)
404                .write(true)
405                .open(file_path)
406                .map_err(|e| anyhow!("Failed to open file: {}", e))?;
407
408            // En Unix, duplicamos el file descriptor
409            let original_fd = original_file.as_raw_fd();
410            let duplicated_fd = unsafe { libc::dup(original_fd) };
411
412            if duplicated_fd == -1 {
413                return Err(anyhow!("Failed to duplicate file descriptor"));
414            }
415
416            info!(
417            "File opened with protection (Unix): {}, original_fd={}, duplicated_fd={}",
418            file_path, original_fd, duplicated_fd
419        );
420
421            Ok((original_file, duplicated_fd))
422        }
423        #[cfg(target_os = "windows")]
424
425        /// Creates or opens the specified file and returns a duplicated handle
426        /// El service.exe mantiene el handle principal para protección contra borrados
427        /// Returns both original and duplicated handles
428        fn create_or_open_protected_file(
429            &mut self,
430            file_path: &str,
431            target_process: HANDLE,
432        ) -> sharing::PisPasResult<(HANDLE, HANDLE)> {
433            info!(
434                "Creating/opening protected file: {}, target process: {:?}",
435                file_path, target_process
436            );
437
438
439            // Crear el directorio si no existe
440            if let Some(parent) = std::path::Path::new(file_path).parent() {
441                std::fs::create_dir_all(parent)
442                    .map_err(|e| anyhow!("Failed to create directory: {}", e))?;
443            }
444
445
446            if let Err(e) = self.verify_and_restore_from_backup(file_path) {
447                warn!("Failed to verify/restore backup for {}: {}", file_path, e);
448            }
449
450            // Convertir path a UTF-16
451            let wide_path: Vec<u16> = std::ffi::OsStr::new(file_path)
452                .encode_wide()
453                .chain(std::iter::once(0))
454                .collect();
455
456            let original_handle = unsafe {
457                CreateFileW(
458                    wide_path.as_ptr(),
459                    GENERIC_READ | GENERIC_WRITE,
460                    FILE_SHARE_READ | FILE_SHARE_WRITE,
461                    std::ptr::null_mut(),
462                    winapi::um::fileapi::OPEN_ALWAYS, // Crear si no existe, abrir si existe
463                    0,
464                    std::ptr::null_mut(),
465                )
466            };
467
468            if original_handle == winapi::um::handleapi::INVALID_HANDLE_VALUE {
469                let error_code = unsafe { GetLastError() };
470                return Err(anyhow!(
471                    "Failed to open file with protection: error code {}",
472                    error_code
473                ));
474            }
475
476            info!("File opened with delete protection: {}", file_path);
477
478            // Duplicate the handle HACIA EL PROCESO DESTINO
479            let mut duplicated_handle: HANDLE = std::ptr::null_mut();
480            let current_process = unsafe { GetCurrentProcess() };
481
482            let result = unsafe {
483                DuplicateHandle(
484                    current_process,
485                    original_handle,
486                    target_process,
487                    &mut duplicated_handle,
488                    0,
489                    1,
490                    DUPLICATE_SAME_ACCESS,
491                )
492            };
493
494            if result == 0 {
495                let error_code = unsafe { GetLastError() };
496                unsafe { CloseHandle(original_handle) };
497                return Err(anyhow!(
498                    "Failed to duplicate handle to target process: error code {}",
499                    error_code
500                ));
501            }
502
503            info!(
504                "Handle duplicated with delete protection for {}: original={:?}, duplicated={:?}",
505                file_path, original_handle, duplicated_handle
506            );
507
508            Ok((original_handle, duplicated_handle))
509        }
510
511        #[cfg(target_os = "windows")]
512        fn close_duplicated_handle_from_map(&mut self) {
513            let mut map_files = self.map_files.write();
514            info!("Closing all duplicated handles in map maps {:?}", map_files);
515
516            for (path, handle_opt) in map_files.iter_mut() {
517                if let Some(safe_handle) = handle_opt {
518                    safe_handle.close_duplicated();
519                    safe_handle.duplicated = None;
520                    info!("Closed duplicated handle for: {}", path);
521                }
522            }
523        }
524
525        fn handle_get_handle_request(
526            &mut self,
527            file_path: &str,
528            stream: Arc<RwLock<TcpStream>>,
529        ) -> sharing::PisPasResult<()> {
530            info!("Handling GET_HANDLE request for file: {}", file_path);
531
532            // Obtener el identificador del proceso target
533            #[cfg(windows)]
534            let target_process = if let Some(process_pair) = &self.process {
535                process_pair.get_handle()
536            } else {
537                error!("No target process available for handle duplication");
538                let response = "HANDLE_ERROR:No target process available";
539                Self::write_stream(stream, response)?;
540                return Ok(());
541            };
542
543            // ✅ Verificar si YA existe el original (después de restart)
544            {
545                let map_files = self.map_files.read();
546                if let Some(Some(handle_pair)) = map_files.get(file_path) {
547                    if handle_pair.has_original() {
548                        info!("Found existing original for: {}, re-duplicating", file_path);
549
550                        #[cfg(windows)]
551                        {
552                            // RE-DUPLICAR el original hacia el NUEVO proceso
553                            let mut new_duplicated: HANDLE = std::ptr::null_mut();
554                            let result = unsafe {
555                                DuplicateHandle(
556                                    GetCurrentProcess(),
557                                    handle_pair.original,  // ← El original que nunca cerramos
558                                    target_process,         // ← El nuevo proceso
559                                    &mut new_duplicated,
560                                    0,
561                                    1,
562                                    DUPLICATE_SAME_ACCESS,
563                                )
564                            };
565
566                            if result != 0 {
567                                drop(map_files); // Liberar read lock
568
569                                // Actualizar el mapa con el nuevo duplicado
570                                let mut map_files = self.map_files.write();
571                                if let Some(Some(hp)) = map_files.get_mut(file_path) {
572                                    hp.duplicated = Some(new_duplicated);
573                                }
574
575                                let response = format!("HANDLE_OK:{}", new_duplicated as usize);
576                                Self::write_stream(stream, &response)?;
577                                info!("Re-duplicated handle successfully: {:?}", new_duplicated);
578                                return Ok(());
579                            } else {
580                                let error_code = unsafe { GetLastError() };
581                                error!("Failed to re-duplicate: error {}", error_code);
582                                // Continuar para crear uno nuevo
583                            }
584                        }
585
586                        #[cfg(unix)]
587                        {
588                            use std::os::fd::AsRawFd;
589
590                            let duplicated_fd = unsafe { libc::dup(handle_pair._original.as_raw_fd()) };
591                            if duplicated_fd != -1 {
592                                drop(map_files);
593
594                                let mut map_files = self.map_files.write();
595                                if let Some(Some(hp)) = map_files.get_mut(file_path) {
596                                    hp.duplicated = Some(duplicated_fd);
597                                }
598
599                                let response = format!("HANDLE_OK:{}", duplicated_fd);
600                                Self::write_stream(stream, &response)?;
601                                info!("Re-duplicated fd successfully: {}", duplicated_fd);
602                                return Ok(());
603                            }
604                        }
605                    }
606                }
607            }
608
609            // Create or open the file and add to map
610            #[cfg(windows)]
611            match self.create_or_open_protected_file(file_path, target_process) {
612                Ok((original_handle, duplicated_handle)) => {
613                    let handle_pair = HandlePair::new(original_handle, Some(duplicated_handle));
614
615                    {
616                        let mut map_files = self.map_files.write();
617                        map_files.insert(file_path.to_string(), Some(handle_pair));
618                    }
619
620                    let response = format!("HANDLE_OK:{}", duplicated_handle as usize);
621                    Self::write_stream(stream, &response)?;
622                    info!("Successfully created and mapped file handle for: {}", file_path);
623                    info!(
624                        "Original handle protected in service: {:?}",
625                        original_handle
626                    );
627                    info!(
628                        "Duplicated handle sent to target process: {:?}",
629                        duplicated_handle
630                    );
631                }
632                Err(e) => {
633                    error!("Failed to create/open protected file {}: {}", file_path, e);
634                    let mut map_files = self.map_files.write();
635                    map_files.insert(file_path.to_string(), None);
636                    let response = format!("HANDLE_ERROR:{}", e);
637                    Self::write_stream(stream, &response)?;
638                }
639            }
640
641            #[cfg(unix)]
642            match self.create_or_open_protected_file(file_path) {
643                Ok((original_file, duplicated_fd)) => {
644                    let handle_pair = HandlePair::new_unix(original_file, file_path.to_string());
645                    // Actualizar con el fd duplicado
646                    let mut handle_pair = handle_pair;
647                    handle_pair.duplicated = Some(duplicated_fd);
648
649                    {
650                        let mut map_files = self.map_files.write();
651                        map_files.insert(file_path.to_string(), Some(handle_pair));
652                    }
653
654                    let response = format!("HANDLE_OK:{}", duplicated_fd);
655                    Self::write_stream(stream, &response)?;
656                    info!("Successfully created and mapped file descriptor for: {}", file_path);
657                }
658                Err(e) => {
659                    error!("Failed to create/open protected file {}: {}", file_path, e);
660                    let mut map_files = self.map_files.write();
661                    map_files.insert(file_path.to_string(), None);
662                    let response = format!("HANDLE_ERROR:{}", e);
663                    Self::write_stream(stream, &response)?;
664                }
665            }
666
667            Ok(())
668        }
669
670
671        /// Verifica si existe backup y restaura si es necesario
672        fn verify_and_restore_from_backup(&self, file_path: &str) -> sharing::PisPasResult<()> {
673            let backup_dir = sharing::paths::user_home();
674
675            if !backup_dir.exists() {
676                info!(
677                    "Backup directory does not exist, creating: {}",
678                    backup_dir.display()
679                );
680                match std::fs::create_dir_all(&backup_dir) {
681                    Ok(_) => info!("Backup directory created: {}", backup_dir.display()),
682                    Err(e) => {
683                        error!("Failed to create backup directory: {}", e);
684                        return Ok(()); // No es crítico
685                    }
686                }
687            }
688
689            info!("🔍 Checking backup directory: {}", backup_dir.display());
690
691            if let Some(filename) = std::path::Path::new(file_path).file_name() {
692                let backup_file_path = backup_dir.join(filename);
693
694                // Si no existe el backup, no hay nada que restaurar
695                if !backup_file_path.exists() {
696                    info!(
697                        "✅ No backup found for: {} - will create new file",
698                        filename.to_string_lossy()
699                    );
700                    return Ok(());
701                }
702
703                info!("🎯 Backup found: {}", backup_file_path.display());
704
705                // Si el archivo original no existe, restaurar desde backup
706                if !std::path::Path::new(file_path).exists() {
707                    info!(
708                        "🔄 Original file missing, restoring from backup: {}",
709                        file_path
710                    );
711
712                    // Crear directorio si no existe
713                    if let Some(parent) = std::path::Path::new(file_path).parent() {
714                        std::fs::create_dir_all(parent).map_err(|e| {
715                            anyhow!("Failed to create directory for restore: {}", e)
716                        })?;
717                    }
718
719                    std::fs::copy(&backup_file_path, file_path)
720                        .map_err(|e| anyhow!("Failed to restore from backup: {}", e))?;
721
722                    info!(
723                        "✅ RESTORED: {} ← {}",
724                        file_path,
725                        backup_file_path.display()
726                    );
727                    return Ok(());
728                }
729
730                // Si el archivo original existe pero es diferente al backup, SIEMPRE sobrescribir
731                match self.files_are_different(file_path, &backup_file_path) {
732                    Ok(true) => {
733                        info!("Files differ, OVERWRITING with backup: {}", file_path);
734                        std::fs::copy(&backup_file_path, file_path)
735                            .map_err(|e| anyhow!("Failed to overwrite with backup: {}", e))?;
736                        info!(
737                            "OVERWRITTEN: {} ← {}",
738                            file_path,
739                            backup_file_path.display()
740                        );
741                    }
742                    Ok(false) => {
743                        info!("Files match, no restoration needed: {}", file_path);
744                    }
745                    Err(e) => {
746                        warn!("Failed to compare files: {}", e);
747                    }
748                }
749            } else {
750                warn!("Could not extract filename from path: {}", file_path);
751            }
752
753            Ok(())
754        }
755
756
757        /// Cierra todos los handles de archivos mapeados al finalizar el servicio
758        pub fn cleanup_file_handles(&mut self) {
759            info!("Cleaning up all mapped file handles");
760            let mut map_files = self.map_files.write();
761
762            for (_, handle_opt) in map_files.iter() {
763                if let Some(safe_handle) = handle_opt {
764                    safe_handle.close_all();
765                }
766            }
767
768            map_files.clear();
769            info!("All file handles cleaned up");
770        }
771
772        /// Lista todos los archivos actualmente mapeados (para debugging)
773        pub fn _list_mapped_files(&self) -> Vec<String> {
774            let map_files = self.map_files.read();
775            map_files.keys().cloned().collect()
776        }
777
778        /// Remueve un archivo específico del mapa y cierra su handle
779        pub fn _remove_file_mapping(&mut self, file_path: &str) -> sharing::PisPasResult<()> {
780            let mut map_files = self.map_files.write();
781
782            if let Some(handle_opt) = map_files.remove(file_path) {
783                if let Some(safe_handle) = handle_opt {
784                    safe_handle.close_all();
785                }
786                info!("File mapping removed: {}", file_path);
787            } else {
788                warn!(
789                    "Attempted to remove non-existent file mapping: {}",
790                    file_path
791                );
792            }
793
794            Ok(())
795        }
796
797        fn write_stream(
798            stream: Arc<RwLock<TcpStream>>,
799            message: &str,
800        ) -> sharing::PisPasResult<()> {
801            match stream.write().write_all(message.as_bytes()) {
802                Ok(_) => {
803                    info!("Message sent: {}", message);
804                    Ok(())
805                }
806                Err(e) => {
807                    error!("Error writing to stream: {:?}", e);
808                    return Err(anyhow!("Error writing to stream: {:?}", e));
809                }
810            }
811        }
812
813        pub fn change_status(&mut self, status: DriverStatus) {
814            info!("Attempting to change status to: {:?}", status);
815
816            let old_status = {
817                let current_status = self.tray_status.read();
818                info!("Current status: {:?}", *current_status);
819                current_status.clone()
820            };
821
822            {
823                let mut tray_status = self.tray_status.write();
824                *tray_status = status.clone();
825                info!("Status successfully changed to: {:?}", *tray_status);
826            }
827
828            // ✅ Forzar notificación si el estado realmente cambió
829            if old_status != status {
830                self.notify_subscriber(&status.to_string());
831            }
832        }
833
834        #[cfg(unix)]
835        fn launch_process(&mut self, _: bool) -> sharing::PisPasResult<DriverStatus> {
836            match sharing::natives::api::get_first_logged_user() {
837                Ok((username, uid)) => {
838                    if let Some(user) = get_user_by_uid(uid) {
839                        let tray_string = format!(
840                            "{}/.config/pispas/{}",
841                            user.home_dir().display(),
842                            sharing::PRINT_SERVICE
843                        );
844                        info!("Launching tray icon for user: {} at path: {}", username, tray_string);
845                        match sharing::natives::api::run_in_all_sessions(&tray_string, "", Some(&username), Some(uid)) {
846                            Ok(pid) => {
847                                self.change_status(DriverStatus::Running);
848                                self.process = Some(MyHandler::new(pid));
849                                self.started = true;
850                                info!("Tray icon launched for user: {} with PID: {}", username, pid);
851                            }
852                            Err(err) => {
853                                self.change_status(DriverStatus::Warning);
854                                self.process = None;
855                                error!("Error launching tray icon: {} for user {}", err, username);
856                            }
857                        }
858                    }
859                }
860                Err(e) => {
861                    self.change_status(DriverStatus::Warning);
862                    self.process = None;
863                    error!("Failed to get first logged user: {}", e);
864                }
865            }
866            Ok(self.tray_status.read().clone())
867        }
868        #[cfg(target_os = "windows")]
869        fn launch_process(&mut self, launch_first: bool) -> sharing::PisPasResult<DriverStatus> {
870            info!(
871                "Launching Print service current thread_id {:?}",
872                thread::current().id()
873            );
874            let print_service = sharing::paths::print_service_path().display().to_string();
875
876            let cmd = format!("\"{}\"", print_service);
877            info!("Command to run: {}", cmd);
878
879            match sharing::natives::api::run_in_all_sessions(
880                &print_service,
881                "",
882                false,
883                launch_first,
884            ) {
885                Ok(proc) => {
886                    if let Some(handler) = proc {
887                        let handler = MyHandler::new(handler);
888                        info!("Handle: {:?}", handler.get_handle());
889                        self.change_status(DriverStatus::Running);
890                        self.process = Some(handler);
891                        self.started = true;
892                        info!("PrintService launched successfully");
893                    } else {
894                        error!("Error launching PrintService: None");
895                    }
896                }
897                Err(e) => {
898                    self.change_status(DriverStatus::Warning);
899                    self.process = None;
900                    return Err(anyhow!("Error launching Pispas Service: {}", e));
901                }
902            }
903            Ok(self.tray_status.read().clone())
904        }
905        #[cfg(target_os = "windows")]
906        pub fn stop_process(&mut self) -> sharing::PisPasResult<DriverStatus> {
907            if let Some(proc_handler) = self.process.as_mut() {
908                info!(
909                    "Stopping Print service current thread_id {:?}",
910                    thread::current().id()
911                );
912                let result = unsafe { TerminateProcess(proc_handler.get_handle(), 1) }; // Código de salida 1
913                if result != 0 {
914                    info!("PrintService stopped");
915                    unsafe { CloseHandle(proc_handler.get_handle()) };
916                    self.change_status(DriverStatus::Stopped);
917                    self.process = None;
918                    self.started = false;
919
920                    // self.cleanup_file_handles();
921                } else {
922                    let error_code = unsafe { GetLastError() };
923                    self.change_status(DriverStatus::Warning);
924                    return Err(anyhow!("Error stopping Pispas Service: {}", error_code));
925                }
926                sharing::proc::kill_process_by_name(sharing::ORDER_KITCHEN);
927            } else {
928                warn!("Stop request for non running service");
929            }
930            Ok(self.tray_status.read().clone())
931        }
932        #[cfg(unix)]
933        fn stop_process(&mut self) -> sharing::PisPasResult<DriverStatus> {
934            if let Some(proc) = self.process.as_mut() {
935                debug!("Stopping PispasModules current thread_id {:?}", std::thread::current().id());
936                match proc.kill() {
937                    Ok(_) => {
938                        debug!("PispasModules stopped");
939                        self.process = None;
940                        self.change_status(DriverStatus::Stopped);
941                    }
942                    Err(e) => {
943                        warn!("Error stopping web-driver: {} (process might already be dead)", e);
944                        self.process = None;
945                        self.change_status(DriverStatus::Stopped);
946                    }
947                }
948            } else {
949                warn!("Stop request for non running service");
950            }
951            //fallback
952            kill_process_by_name(sharing::PRINT_SERVICE);
953            Ok(self.tray_status.read().clone())
954        }
955
956        /// Handles the CLOSE_HANDLE request for a specific file path
957        fn handle_close_handle_request(
958            &mut self,
959            file_path: &str,
960            stream: Arc<RwLock<TcpStream>>,
961        ) -> sharing::PisPasResult<()> {
962            info!("Handling CLOSE_HANDLE request for file: {}", file_path);
963
964            let mut map_files = self.map_files.write();
965
966            if let Some(handle_opt) = map_files.get(file_path) {
967                if let Some(safe_handle) = handle_opt {
968                    if safe_handle.has_original() {
969                        info!("Closing handle for file: {}", file_path);
970                        safe_handle.close_all();
971
972                        // Remove from map after closing
973                        map_files.remove(file_path);
974
975                        // Send success response
976                        let response = "HANDLE_CLOSED:OK";
977                        Self::write_stream(stream, response)?;
978                        info!("Successfully closed and removed handle for: {}", file_path);
979                    } else {
980                        // Handle exists but is invalid
981                        map_files.remove(file_path);
982                        let response = "HANDLE_CLOSED:INVALID";
983                        Self::write_stream(stream, response)?;
984                        info!("Removed invalid handle for: {}", file_path);
985                    }
986                } else {
987                    // Handle entry exists but is None (failed creation)
988                    map_files.remove(file_path);
989                    let response = "HANDLE_CLOSED:NOT_FOUND";
990                    Self::write_stream(stream, response)?;
991                    info!("Removed failed handle entry for: {}", file_path);
992                }
993            } else {
994                // No entry found for this file path
995                let response = "HANDLE_CLOSED:NOT_FOUND";
996                Self::write_stream(stream, response)?;
997                warn!("Attempted to close non-existent handle for: {}", file_path);
998            }
999
1000            Ok(())
1001        }
1002        fn process_message(
1003            pispas_service: Arc<RwLock<Server>>,
1004            message: &str,
1005            stream: Arc<RwLock<TcpStream>>,
1006            needs_close: CancelToken,
1007        ) -> sharing::PisPasResult<()> {
1008            info!("Message received: {}", message);
1009            let action: Action = message.into();
1010            info!("Action: {:?}", action.to_string());
1011            if message == Action::Subscribe.to_string() {
1012                pispas_service.write().subcribe_vector.push(stream.clone());
1013                info!(
1014                    "Subscribed new client, total: {}",
1015                    pispas_service.read().subcribe_vector.len()
1016                );
1017            }
1018            let status = pispas_service.read().tray_status.read().clone();
1019            if message == Action::Restart.to_string() {
1020                if status == DriverStatus::Running || status == DriverStatus::Warning {
1021                    info!(
1022                        "Restart stream request, change tray status to Stopped == {:?}",
1023                        status
1024                    );
1025                    pispas_service.write().change_status(DriverStatus::Restart);
1026                    // sleep(Duration::from_millis(3800));
1027                    // info!("Start stream request, change tray status to Running == {:?}", status);
1028                    // pispas_service.write().change_status(DriverStatus::Running);
1029                } else if status == DriverStatus::Stopped {
1030                    pispas_service.write().change_status(DriverStatus::Launched);
1031                }
1032            }
1033
1034            if message == Action::Stop.to_string() {
1035                pispas_service.write().change_status(DriverStatus::Stopped);
1036                info!(
1037                    "Stop stream request, change tray status to Stopped == {:?}",
1038                    DriverStatus::Stopped
1039                );
1040            }
1041
1042            if message == Action::Start.to_string() && status == DriverStatus::Stopped {
1043                pispas_service.write().change_status(DriverStatus::Launched);
1044                info!(
1045                    "Start stream request, change tray status to Running == {:?}",
1046                    DriverStatus::Launched
1047                );
1048            }
1049
1050            if message == Action::Update.to_string() {
1051                // Use block_on to run the Future synchronously
1052                let rt = tokio::runtime::Runtime::new().unwrap();
1053                rt.block_on(updates::check_and_launch(&sharing::get_version()));
1054            }
1055            if message.starts_with("MessageBox:") {
1056                let msg = message.trim_start_matches("MessageBox:").trim();
1057                if !msg.is_empty() {
1058                    pispas_service
1059                        .write()
1060                        .notify_subscriber(&DriverStatus::MessageBox(msg.to_string()).to_string());
1061                } else {
1062                    info!("No message provided for MessageBox.");
1063                }
1064            }
1065            // Handle GET_HANDLE requests with file path
1066            if let Action::GetHandle(file_path) = &action {
1067                let mut service = pispas_service.write();
1068                service.handle_get_handle_request(&file_path, stream.clone())?;
1069                needs_close.store(true, Ordering::Relaxed);
1070                return Ok(());
1071            }
1072            if let Action::CloseHandle(file_path) = &action {
1073                let mut service = pispas_service.write();
1074                service.handle_close_handle_request(&file_path, stream.clone())?;
1075                needs_close.store(true, Ordering::Relaxed);
1076                return Ok(());
1077            }
1078            if message == Action::Close.to_string() {
1079                let mut service = pispas_service.write();
1080
1081                if let Some(pos) = service
1082                    .subcribe_vector
1083                    .iter()
1084                    .position(|s| Arc::ptr_eq(s, &stream))
1085                {
1086                    service.subcribe_vector.remove(pos);
1087                    info!(
1088                        "Unsubscribed a client, total: {}",
1089                        service.subcribe_vector.len()
1090                    );
1091                }
1092            }
1093            let new_status = pispas_service.read().tray_status.read().clone();
1094            info!("Tray status changed to: {:?}", new_status);
1095            if message == Action::Subscribe.to_string() {
1096                match stream.write().set_nonblocking(true) {
1097                    Ok(_) => {
1098                        info!("Non blocking set");
1099                    }
1100                    Err(e) => {
1101                        info!("Non blocking not available {:?}", e);
1102                    }
1103                };
1104                Self::write_stream(stream, new_status.to_string().as_str())?;
1105            } else {
1106                info!("Close stream request");
1107                needs_close.store(true, Ordering::Relaxed);
1108            }
1109            Ok(())
1110        }
1111
1112        pub fn notify_subscriber(&mut self, message: &str) {
1113            if message == *self.last_status_send.read() {
1114                return;
1115            }
1116            let mut stream_remove = Vec::new();
1117            for (i, sub) in self.subcribe_vector.iter().enumerate() {
1118                match Self::write_stream(sub.clone(), message) {
1119                    Ok(_) => {
1120                        info!("Message to client subcribe sent: {}", message);
1121                        if !message.starts_with("MessageBox:") {
1122                            *self.last_status_send.write() = message.to_string();
1123                        }
1124                    }
1125                    Err(e) => {
1126                        stream_remove.push(i);
1127                        error!("Error writing to stream: {:?}", e);
1128                    }
1129                }
1130            }
1131            if !stream_remove.is_empty() {
1132                for &index in stream_remove.iter().rev() {
1133                    self.subcribe_vector.remove(index);
1134                }
1135            }
1136        }
1137
1138        pub fn handle_message(
1139            pispas_service: Arc<RwLock<Server>>,
1140            stream: Arc<RwLock<TcpStream>>,
1141            stop: CancelToken,
1142        ) {
1143            let need_close = CancelToken::default();
1144            if let Err(e) = stream.write().set_nonblocking(true) {
1145                info!("Non blocking not available {:?}", e);
1146            };
1147            loop {
1148                sleep(Duration::from_millis(DEFAULT_CICLES_TO_WAIT_IN_MS));
1149                if need_close.load(Ordering::Relaxed) || stop.load(Ordering::Relaxed) {
1150                    sleep(Duration::from_millis(DEFAULT_CICLES_TO_WAIT_IN_MS));
1151                    info!("Terminate thread");
1152                    break;
1153                }
1154
1155                let mut buffer = Vec::new(); // Use a dynamic Vec to store the incoming message
1156
1157                loop {
1158                    let mut partial_buffer = [0; 1024];
1159                    match stream.write().read(&mut partial_buffer) {
1160                        Ok(size) => {
1161                            if size == 0 {
1162                                sleep(Duration::from_millis(DEFAULT_CICLES_TO_WAIT_IN_MS)); // Wait a bit before trying again
1163                                continue;
1164                            }
1165                            buffer.extend_from_slice(&partial_buffer[..size]);
1166                            if size < partial_buffer.len() {
1167                                break; // Finished reading the complete message
1168                            }
1169                        }
1170                        Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => {
1171                            // Operation would block, wait a bit and try again
1172                            sleep(Duration::from_millis(DEFAULT_CICLES_TO_WAIT_IN_MS)); // Wait a bit before trying again
1173                            continue;
1174                        }
1175                        Err(e) => {
1176                            error!("Failed to read from socket in dedicated thread: {}", e);
1177                            break;
1178                        }
1179                    }
1180                }
1181
1182                let message = String::from_utf8_lossy(&buffer).to_string();
1183
1184                match Server::process_message(
1185                    pispas_service.clone(),
1186                    &message,
1187                    stream.clone(),
1188                    need_close.clone(),
1189                ) {
1190                    Ok(_) => {}
1191                    Err(e) => {
1192                        error!("Error processing message: {:?}", e);
1193                    }
1194                }
1195                info!("Message processed: {}", message);
1196            }
1197        }
1198
1199        fn watchdog(thread_service: Arc<RwLock<Server>>, thread_cancel: CancelToken) {
1200            //Thread to monitor the process status
1201            thread::spawn(move || loop {
1202                if thread_cancel.load(Ordering::Relaxed) {
1203                    info!("WATCHDOG: Terminate thread, stop requested");
1204                    if let Err(e) = thread_service.write().on_service_stop() {
1205                        error!("Failed to execute service stop cleanup: {}", e);
1206                    }
1207                    match thread_service.write().stop_process() {
1208                        Ok(_) => {
1209                            thread_service
1210                                .write()
1211                                .notify_subscriber(DriverStatus::Stopped.to_string().as_str());
1212                        }
1213                        Err(e) => {
1214                            error!("Failed to stop process {}", e);
1215                        }
1216                    }
1217                    
1218                    sharing::proc::kill_process_by_name(sharing::TRAY_ICON_NAME);
1219                    return;
1220                }
1221
1222                match thread_service.write().check() {
1223                    Ok(_) => {}
1224                    Err(e) => {
1225                        error!("Failed to check process {}", e);
1226                    }
1227                }
1228                #[cfg(target_os = "windows")]
1229                {
1230                    let thread_clone = thread_service.clone();
1231                    Self::still_active_process(thread_clone.clone());
1232                }
1233
1234                sleep(Duration::from_millis(800));
1235            });
1236        }
1237
1238
1239        #[cfg(target_os = "windows")]
1240        fn still_active_process(thread_clone: Arc<RwLock<Server>>) {
1241            let proc_handler = {
1242                let guard = thread_clone.write();
1243                guard.process.clone()
1244            };
1245            if let Some(proc_handler) = proc_handler {
1246                let mut exit_code: u32 = 0;
1247                let ret = unsafe { GetExitCodeProcess(proc_handler.get_handle(), &mut exit_code) };
1248
1249                if ret == 0 {
1250                    error!("Failed to get exit code of process");
1251                    let error_code = unsafe { GetLastError() };
1252                    error!("Error code: {}", error_code);
1253                    let mut guard = thread_clone.write();
1254                    guard.process = None;
1255                } else if exit_code != STILL_ACTIVE {
1256                    // EndProcess
1257                    let status = {
1258                        let guard = thread_clone.read();
1259                        let x = guard.tray_status.read().clone();
1260                        x
1261                    };
1262                    if status == DriverStatus::Running || status == DriverStatus::Warning {
1263                        // change process to None to launch the thread again
1264                        let mut guard = thread_clone.write();
1265                        guard.process = None;
1266                        static EXIT_CODES_TO_IGNORE: &[u32] = &[3221226091, 3228369022, 1073807364];
1267
1268                        if EXIT_CODES_TO_IGNORE.contains(&exit_code) {
1269                            warn!("process exited with code {}, restarting but ignoring warning, changing status to Launched", exit_code);
1270                            guard.change_status(DriverStatus::Launched);
1271                        } else {
1272                            error!("process exited, re*starting with exit_code {}", exit_code);
1273                            guard.change_status(DriverStatus::Warning);
1274                        }
1275                        sleep(Duration::from_millis(1000)); //time to wait before restart
1276                    } else if status != DriverStatus::Stopped {
1277                        info!(
1278                            "process exited, keeping stopped. Driver status: {:?}",
1279                            status
1280                        );
1281                    }
1282                }
1283            }
1284        }
1285
1286        /// Método interno del server para manejar el evento de stop
1287        pub fn on_service_stop(&mut self) -> sharing::PisPasResult<()> {
1288            info!("Service stopping - backing up protected files");
1289
1290            // Usar user_home para backup
1291            let backup_dir = sharing::paths::user_home();
1292
1293            let map_files = self.map_files.read();
1294            let mut backup_count = 0;
1295            info!("Backing up files to: {}", backup_dir.display());
1296            for (original_path, handle_opt) in map_files.iter() {
1297                if let Some(safe_handle) = handle_opt {
1298                    if safe_handle.is_valid() {
1299                        #[cfg(windows)]
1300                        {
1301                            use winapi::um::fileapi::FlushFileBuffers;
1302                            unsafe {
1303                                FlushFileBuffers(safe_handle.original);
1304                            }
1305                        }
1306
1307                        #[cfg(unix)]
1308                        {
1309                            use std::os::unix::io::AsRawFd;
1310                            unsafe {
1311                                libc::fsync(safe_handle._original.as_raw_fd());
1312                            }
1313                        }
1314                        if let Some(filename) = std::path::Path::new(original_path).file_name() {
1315                            let backup_file_path = backup_dir.join(filename);
1316
1317                            match std::fs::copy(original_path, &backup_file_path) {
1318                                Ok(_) => {
1319                                    info!(
1320                                        "Backed up: {} → {}",
1321                                        original_path,
1322                                        backup_file_path.display()
1323                                    );
1324                                    backup_count += 1;
1325                                }
1326                                Err(e) => {
1327                                    error!("Failed to backup {}: {}", original_path, e);
1328                                }
1329                            }
1330                        }
1331                    }
1332                }
1333            }
1334
1335            info!(
1336                "Backup completed: {} files backed up to {}",
1337                backup_count,
1338                backup_dir.display()
1339            );
1340            drop(map_files); // Release the read lock before cleanup
1341            self.cleanup_file_handles();
1342
1343            Ok(())
1344        }
1345
1346        /// Compara si dos archivos son diferentes
1347        fn files_are_different(
1348            &self,
1349            file1: &str,
1350            file2: &std::path::Path,
1351        ) -> sharing::PisPasResult<bool> {
1352            use std::fs;
1353
1354            let content1 =
1355                fs::read(file1).map_err(|e| anyhow!("Failed to read {}: {}", file1, e))?;
1356            let content2 = fs::read(file2)
1357                .map_err(|e| anyhow!("Failed to read {}: {}", file2.display(), e))?;
1358
1359            Ok(content1 != content2)
1360        }
1361
1362        fn start_server(
1363            listener: Arc<RwLock<TcpListener>>,
1364            stop_arc: CancelToken,
1365            pispas_service: Arc<RwLock<Server>>,
1366        ) {
1367            loop {
1368                sleep(Duration::from_millis(DEFAULT_CICLES_TO_WAIT_IN_MS));
1369                for connection in listener.write().incoming() {
1370                    match connection {
1371                        Ok(stream) => {
1372                            info!("New connection");
1373                            let stream_arc = Arc::new(RwLock::new(stream));
1374                            let thread_stream = stream_arc.clone();
1375
1376                            let thread_token = stop_arc.clone();
1377                            let thread_service = pispas_service.clone();
1378                            thread::spawn(move || {
1379                                info!("New thread thread_id: {:?}", thread::current().id());
1380                                Server::handle_message(
1381                                    thread_service.clone(),
1382                                    thread_stream,
1383                                    thread_token,
1384                                );
1385                            });
1386                        }
1387                        Err(_) => {
1388                            sleep(Duration::from_millis(DEFAULT_CICLES_TO_WAIT_IN_MS)); //wait for process stop
1389                            if stop_arc.load(Ordering::Relaxed) {
1390                                if let Err(e) = pispas_service.write().on_service_stop() {
1391                                    error!("Failed to execute service stop cleanup: {}", e);
1392                                }
1393                                info!("STOP KILL KILL server");
1394                                return;
1395                            }
1396                        }
1397                    }
1398                }
1399            }
1400        }
1401
1402        pub fn run_server(pispas_service: Arc<RwLock<Server>>, stop_arc: CancelToken) {
1403            let socket_name = sharing::CHANNEL_NAME;
1404
1405            // 🧹 CLEANUP SIMPLE: Solo remover archivo anterior si existe
1406            if std::path::Path::new(socket_name).exists() {
1407                info!("Removing stale socket file: {}", socket_name);
1408                if let Err(e) = std::fs::remove_file(socket_name) {
1409                    warn!("Failed to remove stale socket, trying anyway: {}", e);
1410                }
1411            }
1412
1413            let listener_result = TcpListener::bind(sharing::CHANNEL_NAME);
1414
1415            let listener = match listener_result {
1416                Ok(listener) => {
1417                    info!("✅ Successfully bound to socket: {}", socket_name);
1418                    listener
1419                }
1420                Err(e) => {
1421                    error!("❌ Error binding to socket: {:?}", e);
1422                    return;
1423                }
1424            };
1425
1426            // 🛡️ SIMPLE CLEANUP ON EXIT: Registrar cleanup para Ctrl+C
1427            let cleanup_socket_name = socket_name.to_string();
1428            let cleanup_stop_arc = stop_arc.clone();
1429
1430            thread::spawn(move || {
1431                while !cleanup_stop_arc.load(Ordering::Relaxed) {
1432                    sleep(Duration::from_millis(3000));
1433                }
1434                info!("🧹 Cleaning up socket on shutdown: {}", cleanup_socket_name);
1435                let _ = std::fs::remove_file(&cleanup_socket_name);
1436            });
1437
1438            if let Err(error) = listener.set_nonblocking(true) {
1439                error!("Failed to set non-blocking: {:?}", error);
1440            }
1441            let thread_cancel = stop_arc.clone();
1442            let listener: Arc<RwLock<TcpListener>> = Arc::new(RwLock::new(listener));
1443            let thread_service = pispas_service.clone();
1444            updates::launch_thread(stop_arc.clone());
1445
1446            Server::watchdog(thread_service.clone(), thread_cancel.clone());
1447
1448            #[cfg(target_os = "macos")]
1449            thread::spawn(move || {
1450                info!("Waiting for user login to launch tray...");
1451
1452                loop {
1453                    if let Ok((username, uid)) = sharing::natives::api::get_first_logged_user() {
1454                        if let Some(user) = get_user_by_uid(uid) {
1455                            let tray_string = format!(
1456                                "{}/.config/pispas/{}",
1457                                user.home_dir().display(),
1458                                sharing::TRAY_ICON_NAME
1459                            );
1460                            info!("User {} logged in, launching tray", username);
1461                            let _ = sharing::natives::api::run_in_all_sessions(&tray_string, "", Some(&username), Some(uid));
1462                            break;
1463                        }
1464                    }
1465                    sleep(Duration::from_secs(3));
1466                }
1467            });
1468
1469
1470            let tray_string = sharing::paths::tray_icon_path().display().to_string();
1471            #[cfg(target_os = "windows")]
1472            if let Err(err) =
1473                sharing::natives::api::run_in_all_sessions(&tray_string, "", true, false)
1474            {
1475                error!("Error launching tray icon: {} for all users", err);
1476            }
1477
1478            #[cfg(not(target_os = "windows"))]
1479            if let Err(err) =
1480                sharing::natives::api::run_in_all_sessions(&tray_string, "", None, None)
1481            {
1482                error!("Error launching tray icon: {} for all users", err);
1483            }
1484
1485            Server::start_server(listener.clone(), stop_arc.clone(), pispas_service.clone());
1486
1487            // 🧹 CLEANUP FINAL
1488            info!("🧹 Final cleanup of socket: {}", socket_name);
1489            let _ = std::fs::remove_file(socket_name);
1490        }
1491	
1492	#[cfg(target_os = "macos")]
1493	 pub fn check(&mut self) -> sharing::PisPasResult<()> {
1494            let status = self.tray_status.read().clone();
1495            if let Some(proc) = self.process.as_mut() {
1496                match proc.try_wait() {
1497                    Ok(Some(exit_status)) => {
1498                        if status == DriverStatus::Running
1499                            || status == DriverStatus::Warning
1500                        {
1501                            tracing::warn!("Web driver process exited with status: {} restarting", exit_status);
1502                            self.launch_process(false)?;
1503                            self.change_status(DriverStatus::Warning);
1504                            self.notify_subscriber(&DriverStatus::Warning.to_string().as_str());
1505                            std::thread::sleep(Duration::from_secs(2));
1506
1507                        } else {
1508                            tracing::warn!("Web driver process exited with status: {} keep stopped", exit_status);
1509                        }
1510                    }
1511                    Err(e) => {
1512                        tracing::error!("Error checking web driver process: {} stopping", e);
1513                    }
1514                    Ok(None) => {
1515                        if status == DriverStatus::Stopped {
1516                            tracing::warn!("Web driver process running with status: {:?}", status);
1517                            self.stop_process()?;
1518                            self.notify_subscriber(&DriverStatus::Stopped.to_string().as_str())
1519                        }
1520                        if status == DriverStatus::Restart {
1521                            warn!("Web driver process running with status: {:?}, restarting", status);
1522                            self.stop_process()?;
1523                            std::thread::sleep(Duration::from_secs(1));
1524                            self.launch_process(false)?;
1525                            self.change_status(DriverStatus::Running);
1526                            self.notify_subscriber(&self.tray_status.clone().read().to_string().as_str());
1527                        }
1528                    }
1529                }
1530            }
1531            else{
1532                if status == DriverStatus::Running || status == DriverStatus::Launched {
1533                    tracing::warn!("Web driver process launched with status: {:?}", status);
1534                    self.launch_process(false)?;
1535                    self.change_status(DriverStatus::Running);
1536                    self.notify_subscriber(&self.tray_status.clone().read().to_string().as_str());
1537                }
1538                debug!("Web driver process is None, launching new process");
1539                debug!("status: {:?}", status);
1540            }
1541
1542            Ok(())
1543        }	
1544    
1545    	#[cfg(target_os = "windows")]
1546        pub fn check(&mut self) -> sharing::PisPasResult<()> {
1547            let status = {
1548                let guard = self.tray_status.read();
1549                guard.clone()
1550            };
1551
1552            match self.process {
1553                Some(_) => {
1554                    match status {
1555                        DriverStatus::Stopped => {
1556                            warn!("PrintService process stopped with status: {:?}", status);
1557                            self.stop_process()?;
1558                            self.close_duplicated_handle_from_map();
1559                            self.notify_subscriber(&status.to_string());
1560                        }
1561                        DriverStatus::Launched => {
1562                            self.change_status(DriverStatus::Running);
1563                        }
1564                        DriverStatus::Restart => {
1565                            warn!("PrintService process restarted with status: {:?}", status);
1566                            self.close_duplicated_handle_from_map();
1567                            self.stop_process()?;
1568                            sleep(Duration::from_millis(700));
1569                            self.launch_process(false)?;
1570                            sleep(Duration::from_millis(700));
1571                            self.change_status(DriverStatus::Running);
1572                            let new_status = {
1573                                let guard = self.tray_status.read();
1574                                guard.to_string()
1575                            };
1576                            self.notify_subscriber(&new_status);
1577                        }
1578                        _ => {} // Otros estados no necesitan acción cuando hay proceso
1579                    }
1580                }
1581                None => {
1582                    match status {
1583                        DriverStatus::Launched | DriverStatus::Running => {
1584                            warn!("PrintService process launched with status: {:?}", status);
1585                            let is_launched = !self.started;
1586                            self.launch_process(is_launched)?;
1587                            self.change_status(DriverStatus::Running);
1588                            let new_status = {
1589                                let guard = self.tray_status.read();
1590                                guard.to_string()
1591                            };
1592                            self.notify_subscriber(&new_status);
1593                        }
1594                        DriverStatus::Warning => {
1595                            warn!("PrintService process warning with status: {:?}", status);
1596                            self.close_duplicated_handle_from_map();
1597                            self.launch_process(false)?;
1598                            self.change_status(DriverStatus::Warning);
1599                            let new_status = {
1600                                let guard = self.tray_status.read();
1601                                guard.to_string()
1602                            };
1603                            self.notify_subscriber(&new_status);
1604                        }
1605                        DriverStatus::Stopped => {
1606                            self.close_duplicated_handle_from_map();
1607                            debug!("PrintService process stopped with status: {:?}", status);
1608                            if self.started {
1609                                self.change_status(DriverStatus::Stopped);
1610                                self.notify_subscriber(&status.to_string());
1611                            }
1612                        }
1613                        _ => {} // Otros estados
1614                    }
1615                }
1616            }
1617            Ok(())
1618        }
1619    }
1620}
1621
1622pub use pispas_server::*;
1623