use super::driver_tools::{DriverTools, NativeDriverTools};
use super::join_definition::{JoinDefinition, NativeJoinDefinition};
use super::member_sql::{CompiledMemberTemplate, MemberSql, NativeMemberSql};
use super::pre_aggregation_obj::{NativePreAggregationObj, PreAggregationObj};
use super::security_context::{NativeSecurityContext, SecurityContext};
use super::sql_templates_render::{NativeSqlTemplatesRender, SqlTemplatesRender};
use super::sql_utils::{NativeSqlUtils, SqlUtils};
use crate::cube_bridge::base_query_options::FilterValue;
use crate::cube_bridge::join_hints::JoinHintItem;
use cubenativeutils::wrappers::serializer::{
    NativeDeserialize, NativeDeserializer, NativeSerialize,
};
use cubenativeutils::wrappers::NativeContextHolder;
use cubenativeutils::wrappers::NativeObjectHandle;
use cubenativeutils::CubeError;
use std::any::Any;
use std::rc::Rc;

/// Dialect-independent callbacks to the JavaScript side, used
/// during compilation and planning: SQL templates, allocated params,
/// pre-aggregation lookup, join-tree resolution. Dialect-specific
/// helpers live behind `DriverTools`, reachable via `driver_tools()`.
#[nativebridge::native_bridge]
pub trait BaseTools {
    fn driver_tools(&self, external: bool) -> Result<Rc<dyn DriverTools>, CubeError>;
    fn sql_templates(&self) -> Result<Rc<dyn SqlTemplatesRender>, CubeError>;
    fn sql_utils_for_rust(&self) -> Result<Rc<dyn SqlUtils>, CubeError>;
    fn get_allocated_params(&self) -> Result<Vec<FilterValue>, CubeError>;
    fn all_cube_members(&self, path: String) -> Result<Vec<String>, CubeError>;
    fn interval_and_minimal_time_unit(&self, interval: String) -> Result<Vec<String>, CubeError>;
    fn get_pre_aggregation_by_name(
        &self,
        cube_name: String,
        name: String,
    ) -> Result<Rc<dyn PreAggregationObj>, CubeError>;
    fn pre_aggregation_table_name(
        &self,
        cube_name: String,
        name: String,
    ) -> Result<String, CubeError>; //TODO move to rust

    fn join_tree_for_hints(
        &self,
        hints: Vec<JoinHintItem>,
    ) -> Result<Rc<dyn JoinDefinition>, CubeError>;

    fn compile_member_sql(
        &self,
        member_sql: Rc<dyn MemberSql>,
        security_context: Rc<dyn SecurityContext>,
        arg_names: Vec<String>,
    ) -> Result<CompiledMemberTemplate, CubeError>;
}
