use serde_json::Value as JsonValue;
use std::{fmt::Debug, future::Future, pin::Pin};

#[derive(Debug, Clone)]
pub struct CloudServiceContext {}

impl CloudServiceContext {
    pub fn new() -> Self {
        Self {}
    }
    pub fn empty() -> Self {
        Self {}
    }
}

pub trait AuthenticatedCloudServiceRouter: Send + Sync + Debug {
    fn route<'a>(
        &'a self,
        service: CloudService,
    ) -> Pin<Box<dyn Future<Output = Result<String, String>> + Send + 'a>>;
}

#[derive(Debug, Clone)]
pub enum CloudService {
    Registry,
    Id,
    Svm(SvmService),
    Evm,
}

impl CloudService {
    pub fn svm_subgraph(url: &str, params: JsonValue, do_include_token: bool) -> Self {
        Self::Svm(SvmService::DeploySubgraph(DeploySubgraphCommand {
            url: url.to_string(),
            params,
            do_include_token,
        }))
    }
    pub fn svm_register_idl(
        url: &str,
        params: JsonValue,
        do_include_token: bool,
        is_surfnet: bool,
    ) -> Self {
        Self::Svm(SvmService::RegisterIdl(RegisterIdlCommand {
            url: url.to_string(),
            params,
            do_include_token,
            is_surfnet,
        }))
    }
    pub fn token_required(&self) -> bool {
        match self {
            CloudService::Registry => false,
            CloudService::Id => false,
            CloudService::Svm(SvmService::DeploySubgraph(cmd)) => cmd.do_include_token,
            CloudService::Svm(SvmService::RegisterIdl(cmd)) => cmd.do_include_token,
            CloudService::Evm => false,
        }
    }
}

#[derive(Debug, Clone)]
pub enum SvmService {
    DeploySubgraph(DeploySubgraphCommand),
    RegisterIdl(RegisterIdlCommand),
}

#[derive(Debug, Clone)]
pub struct DeploySubgraphCommand {
    pub url: String,
    pub params: JsonValue,
    pub do_include_token: bool,
}

#[derive(Debug, Clone)]
pub struct RegisterIdlCommand {
    pub url: String,
    pub params: JsonValue,
    pub do_include_token: bool,
    pub is_surfnet: bool,
}
