Skip to main content

game_manager_lib/commands/platforms/
scanner.rs

1//! Escaneia uma pasta local em busca de possíveis jogos.
2//!
3//! Retorna uma lista de descobertas encontradas.
4
5use crate::commands::platforms::core::{
6    format_import_summary, persist_source_games, ScanGameInput, ScanResult,
7};
8use crate::database::AppState;
9use crate::errors::AppError;
10use crate::sources::scanner::scan_folder;
11use std::path::Path;
12use tauri::{AppHandle, Emitter, State};
13use tracing::info;
14
15#[tauri::command]
16pub async fn scan_games_folder(folder_path: String) -> Result<ScanResult, String> {
17    let path = Path::new(&folder_path);
18
19    // Validações básicas
20    if !path.exists() {
21        return Ok(ScanResult {
22            success: false,
23            message: "Pasta não encontrada".to_string(),
24            discoveries: vec![],
25        });
26    }
27
28    if !path.is_dir() {
29        return Ok(ScanResult {
30            success: false,
31            message: "Caminho não é uma pasta".to_string(),
32            discoveries: vec![],
33        });
34    }
35
36    // Executar scan
37    let discoveries = scan_folder(path)?;
38
39    let message = if discoveries.is_empty() {
40        "Nenhum jogo encontrado nesta pasta".to_string()
41    } else {
42        format!("Encontrados {} possíveis jogos", discoveries.len())
43    };
44
45    Ok(ScanResult {
46        success: true,
47        message,
48        discoveries,
49    })
50}
51
52/// Adiciona um jogo descoberto pelo scan ao banco de dados.
53#[tauri::command]
54pub async fn add_game_from_scan(
55    app: AppHandle,
56    state: State<'_, AppState>,
57    name: String,
58    executable_path: String,
59    base_path: String,
60) -> Result<String, AppError> {
61    use crate::sources::providers::SourceGame;
62
63    let game = SourceGame {
64        platform: "Outra".to_string(),
65        platform_game_id: executable_path.clone(),
66        name: Some(name),
67        installed: true,
68        executable_path: Some(executable_path.clone()),
69        install_path: Some(base_path),
70        playtime_minutes: Some(0),
71        last_played: None,
72    };
73
74    let (inserted, _, _) = persist_source_games(&state, vec![game]).await?;
75
76    if inserted == 0 {
77        return Err(AppError::ValidationError(
78            "Este jogo já foi adicionado anteriormente.".to_string(),
79        ));
80    }
81
82    let _ = app.emit("library_updated", ());
83
84    Ok("Jogo adicionado com sucesso.".to_string())
85}
86
87/// Adiciona múltiplos jogos descobertos pelo scan ao banco de dados.
88#[tauri::command]
89pub async fn add_games_from_scan(
90    app: AppHandle,
91    state: State<'_, AppState>,
92    games: Vec<ScanGameInput>,
93) -> Result<String, AppError> {
94    use crate::sources::providers::SourceGame;
95
96    let source_games: Vec<SourceGame> = games
97        .into_iter()
98        .map(|g| SourceGame {
99            platform: "Outra".to_string(),
100            platform_game_id: g.executable_path.clone(),
101            name: Some(g.name),
102            installed: true,
103            executable_path: Some(g.executable_path.clone()),
104            install_path: Some(g.base_path),
105            playtime_minutes: Some(0),
106            last_played: None,
107        })
108        .collect();
109
110    let (inserted, updated, _newly_imported) = persist_source_games(&state, source_games).await?;
111    let message = format_import_summary("Local", inserted, updated);
112    info!("{}", message);
113
114    let _ = app.emit("library_updated", ());
115
116    Ok(message)
117}