/*
 * mCaptcha - A proof of work based DoS protection system
 * Copyright © 2023 Aravinth Manivannan <realravinth@batsense.net>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
use std::collections::BTreeMap;
use std::sync::Arc;

use openraft::error::RaftError;
use openraft::BasicNode;
use openraft::Config;

use crate::network::raft_network_impl::DcacheNetwork;
//use crate::network::raft_network_impl::HealthLedger;
use crate::typ::InitializeError;
use crate::DcacheNodeId;
use crate::DcacheRaft;
use crate::DcacheStore;

// Representation of an application state. This struct can be shared around to share
// instances of raft, store and more.
pub struct DcacheApp {
    pub id: DcacheNodeId,
    pub addr: String,
    pub raft: DcacheRaft,
    pub store: Arc<DcacheStore>,
    pub config: Arc<Config>,
    pub network: Arc<DcacheNetwork>,
}

impl DcacheApp {
    //    //    pub async fn introduce(&self) {
    //    //        for (node_id, http_addr) =
    //    //
    //    //    let req: (DcacheNodeId, String) = (node_id, http_addr);
    //    //    let c =reqwest::Client::new();
    //    //    c.post(
    //    //        format!("http://{}/add-learner", introducer_addr)).json(&req).send().await.unwrap();
    //    //
    //    //    }
    //
    //    //    pub async fn change_membership(&self) {
    //    //        let r= self.network.online.read().unwrap();
    //    //        self.raft.change_membership(&*r, false).await
    //    //    }
    //    //
    //    //    pub fn mark_node_online(&self,
    //    //
    //    //        (node_id, node_addr): (DcacheNodeId, String)
    //    //        ) {
    //    //        let mut w= self.network.online.write().unwrap();
    //    //        if w.get(node_id).is_some() {
    //    //            return;
    //    //        }
    //    //
    //    //        w.insert(node_id, node_addr);
    //    //    }
    //
    pub async fn init(&self) -> Result<(), RaftError<u64, InitializeError>> {
        let mut nodes = BTreeMap::new();
        nodes.insert(
            self.id,
            BasicNode {
                addr: self.addr.clone(),
            },
        );
        self.raft.initialize(nodes).await
    }
}
