// Copyright 2026 Gregorio Momm
// Licensed under the Apache License, Version 2.0

//! `AlgorithmEngine` implementation for `NetworKitRustBackend`.
//!
//! All methods delegate to the native algorithm methods in `native_algorithms.rs`
//! which operate directly on the internal NetworKit adjacency list — no copy needed.

use std::collections::{HashMap, HashSet};

use crate::graph::algorithm_engine::{AlgorithmEngine, MaxFlowResult};
use crate::graph::backends::petgraph_algorithms::CommunityInfo;
use super::backend::NetworKitRustBackend;

impl AlgorithmEngine for NetworKitRustBackend {
    // ── Centrality ────────────────────────────────────────────────────────

    fn degree_centrality(&self) -> HashMap<u64, f64> {
        self.degree_centrality()
    }

    fn betweenness_centrality(&self, normalized: bool) -> HashMap<u64, f64> {
        self.betweenness_centrality(normalized)
    }

    fn closeness_centrality(&self, normalized: bool) -> HashMap<u64, f64> {
        self.closeness_centrality(normalized)
    }

    fn pagerank(&self, damping: f64, max_iter: usize) -> HashMap<u64, f64> {
        self.pagerank(damping, max_iter)
    }

    // ── Pathfinding ───────────────────────────────────────────────────────

    fn bfs_path(&self, source: u64, target: u64) -> Option<Vec<u64>> {
        self.bfs_path(source, target)
    }

    fn dijkstra_path(&self, source: u64, target: u64) -> Option<(f64, Vec<u64>)> {
        self.dijkstra_path(source, target)
    }

    fn astar_path<F>(&self, source: u64, target: u64, heuristic: F) -> Option<(f64, Vec<u64>)>
    where
        F: Fn(u64) -> f64,
    {
        self.astar_path(source, target, heuristic)
    }

    fn bellman_ford_distances(&self, source: u64) -> Option<HashMap<u64, f64>> {
        self.bellman_ford_distances(source)
    }

    fn floyd_warshall_distances(&self) -> HashMap<(u64, u64), f64> {
        self.floyd_warshall_distances()
    }

    fn all_pairs_distances(&self) -> HashMap<u64, HashMap<u64, f64>> {
        self.all_pairs_distances()
    }

    // ── Spanning Trees ────────────────────────────────────────────────────

    fn minimum_spanning_tree(&self) -> Vec<(u64, u64, f64)> {
        self.minimum_spanning_tree()
    }

    fn maximum_spanning_tree(&self) -> Vec<(u64, u64, f64)> {
        self.maximum_spanning_tree()
    }

    // ── DAG Algorithms ────────────────────────────────────────────────────

    fn topological_sort(&self) -> Result<Vec<u64>, Vec<u64>> {
        self.topological_sort()
    }

    fn is_dag(&self) -> bool {
        self.is_dag()
    }

    fn find_cycles(&self) -> Vec<Vec<u64>> {
        self.find_cycles()
    }

    fn dag_longest_path(&self) -> Option<(usize, Vec<u64>)> {
        self.dag_longest_path()
    }

    fn dag_longest_path_weighted(&self) -> Option<(f64, Vec<u64>)> {
        self.dag_longest_path_weighted()
    }

    fn transitive_closure(&self) -> HashSet<(u64, u64)> {
        // NK native returns Vec; convert to HashSet for the unified interface
        self.transitive_closure().into_iter().collect()
    }

    // ── Network Flow ──────────────────────────────────────────────────────

    fn max_flow(&self, source: u64, sink: u64) -> MaxFlowResult {
        self.max_flow(source, sink)
    }

    fn min_cut_capacity(&self, source: u64, sink: u64) -> Option<f64> {
        self.min_cut_capacity(source, sink)
    }

    // ── Coloring ──────────────────────────────────────────────────────────

    fn node_coloring(&self) -> HashMap<u64, usize> {
        self.node_coloring()
    }

    fn edge_coloring(&self) -> HashMap<(u64, u64), usize> {
        self.edge_coloring()
    }

    fn chromatic_number(&self) -> usize {
        self.chromatic_number()
    }

    // ── Matching ──────────────────────────────────────────────────────────

    fn max_weight_matching_edges(&self) -> HashSet<(u64, u64)> {
        // NK native returns Vec; convert to HashSet
        NetworKitRustBackend::max_weight_matching_edges(self).into_iter().collect()
    }

    fn max_cardinality_matching_edges(&self) -> HashSet<(u64, u64)> {
        NetworKitRustBackend::max_cardinality_matching_edges(self).into_iter().collect()
    }

    // ── Community Detection ───────────────────────────────────────────────

    fn louvain_communities(&self, resolution: Option<f64>) -> CommunityInfo {
        self.louvain_communities(resolution)
    }

    fn label_propagation_communities(&self) -> CommunityInfo {
        self.label_propagation_communities()
    }

    fn girvan_newman_communities(&self, k: usize) -> CommunityInfo {
        self.girvan_newman_communities(k)
    }

    // ── Components ────────────────────────────────────────────────────────

    fn connected_components_list(&self) -> Vec<Vec<u64>> {
        self.connected_components_list()
    }

    fn strongly_connected_components_list(&self) -> Vec<Vec<u64>> {
        self.strongly_connected_components_list()
    }

    // ── Eulerian ──────────────────────────────────────────────────────────

    fn has_euler_circuit(&self) -> bool {
        self.has_euler_circuit()
    }

    fn has_euler_path(&self) -> bool {
        self.has_euler_path()
    }

    fn euler_circuit(&self) -> Option<Vec<u64>> {
        self.euler_circuit()
    }

    fn euler_path(&self) -> Option<Vec<u64>> {
        self.euler_path()
    }

    // ── Planarity ─────────────────────────────────────────────────────────

    fn is_planar(&self) -> bool {
        self.is_planar()
    }
}
