use std::{
    sync::Arc,
    time::{Duration, Instant},
};
use parking_lot::Mutex;
use sp_consensus::SyncOracle as SyncOracleT;
const OFFLINE_THRESHOLD: Duration = Duration::from_secs(6);
const FAR_BEHIND_THRESHOLD: u32 = 15;
const MAJOR_SYNC_THRESHOLD: Duration = Duration::from_secs(10);
#[derive(Clone)]
pub struct SyncOracle {
    last_far_behind: Arc<Mutex<Instant>>,
    last_update: Arc<Mutex<Instant>>,
}
impl SyncOracle {
    pub fn new() -> Self {
        SyncOracle {
            last_update: Arc::new(Mutex::new(Instant::now() - OFFLINE_THRESHOLD)),
            last_far_behind: Arc::new(Mutex::new(Instant::now())),
        }
    }
    pub fn update_behind(&self, behind: u32) {
        let now = Instant::now();
        *self.last_update.lock() = now;
        if behind > FAR_BEHIND_THRESHOLD {
            *self.last_far_behind.lock() = now;
        }
    }
    pub fn major_sync(&self) -> bool {
        self.last_far_behind.lock().elapsed() < MAJOR_SYNC_THRESHOLD
    }
}
impl Default for SyncOracle {
    fn default() -> Self {
        SyncOracle::new()
    }
}
impl SyncOracleT for SyncOracle {
    fn is_major_syncing(&self) -> bool {
        self.major_sync()
    }
    fn is_offline(&self) -> bool {
        self.last_update.lock().elapsed() > OFFLINE_THRESHOLD
    }
}