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