// Copyright 2017 TiKV Project Authors. Licensed under Apache-2.0.
// Modifications Copyright 2022 PingCAP, Inc.
// #[PerformanceCriticalPath]
use std::fmt::Debug;

use crate::coprocessor::ObserveHandle;

#[derive(Debug)]
pub enum ObserverType {
    Cdc(ObserveHandle),
    Rts(ObserveHandle),
    Pitr(ObserveHandle),
}

impl ObserverType {
    pub fn handle(&self) -> &ObserveHandle {
        match self {
            ObserverType::Cdc(h) => h,
            ObserverType::Rts(h) => h,
            ObserverType::Pitr(h) => h,
        }
    }
}

#[derive(Debug)]
pub struct ChangeObserver {
    pub ty: ObserverType,
    pub region_id: u64,
}

impl ChangeObserver {
    pub fn from_cdc(region_id: u64, id: ObserveHandle) -> Self {
        Self {
            ty: ObserverType::Cdc(id),
            region_id,
        }
    }

    pub fn from_rts(region_id: u64, id: ObserveHandle) -> Self {
        Self {
            ty: ObserverType::Rts(id),
            region_id,
        }
    }

    pub fn from_pitr(region_id: u64, id: ObserveHandle) -> Self {
        Self {
            ty: ObserverType::Pitr(id),
            region_id,
        }
    }
}

pub mod confchange_cmd_metric {
    use raft::eraftpb::ConfChangeType;

    use crate::store::metrics::PEER_ADMIN_CMD_COUNTER;

    pub fn inc_all(cct: ConfChangeType) {
        let metrics = match cct {
            ConfChangeType::AddNode => &PEER_ADMIN_CMD_COUNTER.add_peer,
            ConfChangeType::RemoveNode => &PEER_ADMIN_CMD_COUNTER.remove_peer,
            ConfChangeType::AddLearnerNode => &PEER_ADMIN_CMD_COUNTER.add_learner,
        };
        metrics.all.inc();
    }

    pub fn inc_success(cct: ConfChangeType) {
        let metrics = match cct {
            ConfChangeType::AddNode => &PEER_ADMIN_CMD_COUNTER.add_peer,
            ConfChangeType::RemoveNode => &PEER_ADMIN_CMD_COUNTER.remove_peer,
            ConfChangeType::AddLearnerNode => &PEER_ADMIN_CMD_COUNTER.add_learner,
        };
        metrics.success.inc();
    }
}
