/*
    This file is part of jellything (https://codeberg.org/metamuffin/jellything)
    which is licensed under the GNU Affero General Public License (version 3); see /COPYING.
    Copyright (C) 2026 metamuffin <metamuffin.org>
*/
pub mod acoustid;
pub mod infojson;
pub mod media_info;
pub mod misc;
pub mod musicbrainz;
pub mod tags;
pub mod tmdb;
pub mod trakt;
pub mod vgmdb;
pub mod wikidata;
pub mod wikimedia_commons;

use crate::{ApiSecrets, InheritedFlags};
use anyhow::Result;
use jellycommon::{Node, NodeID};
use jellydb::Database;
use jellyremuxer::matroska::Segment;
use std::{collections::HashSet, path::Path, sync::Mutex};
use tokio::runtime::Handle;

pub struct ImportContext<'a> {
    pub db: &'a Database,
    pub rt: &'a Handle,
    pub iflags: InheritedFlags,
    pub nodes: &'a Mutex<HashSet<NodeID>>,
}

#[derive(Default, Clone, Copy)]
pub struct PluginInfo {
    pub name: &'static str,
    pub handle_file: bool,
    pub handle_media: bool,
    pub handle_instruction: bool,
    pub handle_process: bool,
}

pub trait ImportPlugin: Send + Sync {
    fn info(&self) -> PluginInfo;
    fn file(&self, ct: &ImportContext, parent: NodeID, path: &Path) -> Result<()> {
        let _ = (ct, parent, path);
        Ok(())
    }
    fn media(&self, ct: &ImportContext, node: NodeID, path: &Path, seg: &Segment) -> Result<()> {
        let _ = (ct, node, path, seg);
        Ok(())
    }
    fn instruction(&self, ct: &ImportContext, node: NodeID, line: &str) -> Result<()> {
        let _ = (ct, node, line);
        Ok(())
    }
    fn process(&self, ct: &ImportContext, node: NodeID, data: &Node) -> Result<()> {
        let _ = (ct, node, data);
        Ok(())
    }
}

pub fn init_plugins(secrets: &ApiSecrets) -> Vec<Box<dyn ImportPlugin>> {
    let mut plugins = Vec::<Box<dyn ImportPlugin>>::new();

    plugins.push(Box::new(misc::General));
    plugins.push(Box::new(misc::Children));
    plugins.push(Box::new(misc::ImageAttachments));
    plugins.push(Box::new(misc::ImageFiles));
    plugins.push(Box::new(misc::EpisodeIndex));
    plugins.push(Box::new(tags::Tags));
    plugins.push(Box::new(media_info::MediaInfo));
    plugins.push(Box::new(infojson::Infojson));
    if let Some(api_key) = &secrets.trakt {
        plugins.push(Box::new(trakt::Trakt::new(&api_key)));
    }
    if let Some(api_key) = &secrets.tmdb {
        plugins.push(Box::new(tmdb::Tmdb::new(&api_key))); // deps: trakt
    }
    if let Some(api_key) = &secrets.acoustid {
        plugins.push(Box::new(acoustid::AcoustID::new(&api_key)));
    }
    plugins.push(Box::new(musicbrainz::MusicBrainz::new())); // deps: acoustid
    plugins.push(Box::new(wikidata::Wikidata::new())); // deps: musicbrainz
    plugins.push(Box::new(wikimedia_commons::WikimediaCommons::new())); // deps: wikidata
    plugins.push(Box::new(vgmdb::Vgmdb::new())); // deps: wikidata

    plugins
}
