// Copyright (c) 2019-2022 Alibaba Cloud
// Copyright (c) 2019-2022 Ant Group
//
// SPDX-License-Identifier: Apache-2.0
//

pub mod l3_forwarding_model;
pub mod none_model;
mod port_forwarding;
pub mod tc_filter_model;
pub mod test_network_model;
use std::sync::Arc;

use anyhow::{Context, Result};
use async_trait::async_trait;

use super::NetworkPair;

pub(crate) const TC_FILTER_NET_MODEL_STR: &str = "tcfilter";
pub(crate) const L3_FORWARDING_NET_MODEL_STR: &str = "l3forwarding";

pub enum NetworkModelType {
    NoneModel,
    TcFilter,
    L3Forwarding,
}

#[async_trait]
pub trait NetworkModel: std::fmt::Debug + Send + Sync {
    fn model_type(&self) -> NetworkModelType;
    async fn add(&self, net_pair: &NetworkPair) -> Result<()>;
    async fn del(&self, net_pair: &NetworkPair) -> Result<()>;
}

pub fn new(model: &str) -> Result<Arc<dyn NetworkModel>> {
    match model {
        TC_FILTER_NET_MODEL_STR => Ok(Arc::new(
            tc_filter_model::TcFilterModel::new().context("new tc filter model")?,
        )),
        L3_FORWARDING_NET_MODEL_STR => Ok(Arc::new(
            l3_forwarding_model::L3ForwardingModel::new().context("new l3 forwarding model")?,
        )),
        _ => Ok(Arc::new(
            none_model::NoneModel::new().context("new none model")?,
        )),
    }
}
