wdext 0.1.0

A DbgEng wrapper framework
// SPDX-FileCopyrightText: 2026 takubokudori
// SPDX-License-Identifier: MIT OR Apache-2.0
use crate::{dbgeng::WinResult, dbgmodel::*, *};
use windows::Win32::System::Diagnostics::Debug::Extensions::IDataModelManager2;

impl_debug_interface!(
    DataModelManager,
    DataModelManagerRef,
    IDataModelManager2,
    IDataModelManager
);

// IDataModelManager
impl DataModelManager {
    pub fn close(&self) -> WinResult<()> { unsafe { self.0.Close() } }

    pub fn create_no_value(&self) -> WinResult<ModelObject> {
        unsafe { Ok(self.0.CreateNoValue()?.into()) }
    }

    pub fn create_error_object(
        &self,
        hr: HRESULT,
        message: impl AsRef<WStr>,
    ) -> WinResult<ModelObject> {
        unsafe { Ok(self.0.CreateErrorObject(hr, pcw!(message))?.into()) }
    }

    pub fn create_typed_object<'a>(
        &self,
        context: impl Into<HostContextBy<'a>>,
        object_location: Location,
        object_type: &DebugHostType,
    ) -> WinResult<ModelObject> {
        unsafe {
            Ok(self
                .0
                .CreateTypedObject(
                    context.into().as_raw(),
                    object_location,
                    object_type.as_raw(),
                )?
                .into())
        }
    }

    pub fn create_typed_object_reference<'a>(
        &self,
        context: impl Into<HostContextBy<'a>>,
        object_location: Location,
        object_type: &DebugHostType,
    ) -> WinResult<ModelObject> {
        unsafe {
            Ok(self
                .0
                .CreateTypedObjectReference(
                    context.into().as_raw(),
                    object_location,
                    object_type.as_raw(),
                )?
                .into())
        }
    }

    pub fn create_synthetic_object<'a>(
        &self,
        context: impl Into<HostContextBy<'a>>,
    ) -> WinResult<ModelObject> {
        unsafe {
            Ok(self
                .0
                .CreateSyntheticObject(context.into().as_raw())?
                .into())
        }
    }

    /// # Safety
    pub unsafe fn create_data_model_object(
        &self,
        data_model: DataModelConceptAdapter,
    ) -> WinResult<ModelObject> {
        let data_model: IDataModelConcept = data_model.into();
        unsafe { Ok(self.0.CreateDataModelObject(&data_model)?.into()) }
    }

    pub fn create_intrinsic_object(
        &self,
        object_kind: WdModelObjectKind,
        intrinsic_data: &Variant,
    ) -> WinResult<ModelObject> {
        unsafe {
            Ok(self
                .0
                .CreateIntrinsicObject(
                    object_kind.into(),
                    intrinsic_data.as_ref(),
                )?
                .into())
        }
    }

    pub fn create_typed_intrinsic_object(
        &self,
        intrinsic_data: &Variant,
        r#type: &DebugHostType,
    ) -> WinResult<ModelObject> {
        unsafe {
            Ok(self
                .0
                .CreateTypedIntrinsicObject(
                    intrinsic_data.as_ref(),
                    r#type.as_raw(),
                )?
                .into())
        }
    }

    pub fn get_model_for_type_signature(
        &self,
        type_signature: &DebugHostTypeSignature,
    ) -> WinResult<ModelObject> {
        unsafe {
            Ok(self
                .0
                .GetModelForTypeSignature(type_signature.as_raw())?
                .into())
        }
    }

    pub fn get_model_for_type(
        &self,
        r#type: &DebugHostType,
    ) -> WinResult<(
        ModelObject,
        Option<DebugHostTypeSignature>,
        Option<DebugHostSymbolEnumerator>,
    )> {
        let mut data_model = None;
        let mut type_signature = None;
        let mut wildcard_matches = None;
        unsafe {
            self.0.GetModelForType(
                r#type.as_raw(),
                &mut data_model,
                Some(&mut type_signature),
                Some(&mut wildcard_matches),
            )?;
        }
        Ok((
            data_model.unwrap().into(),
            type_signature.map(Into::into),
            wildcard_matches.map(Into::into),
        ))
    }

    pub fn register_model_for_type_signature(
        &self,
        type_signature: &DebugHostTypeSignature,
        data_model: &ModelObject,
    ) -> WinResult<()> {
        unsafe {
            self.0.RegisterModelForTypeSignature(
                type_signature.as_raw(),
                data_model.as_raw(),
            )
        }
    }

    pub fn unregister_model_for_type_signature(
        &self,
        data_model: &ModelObject,
        type_signature: &DebugHostTypeSignature,
    ) -> WinResult<()> {
        unsafe {
            self.0.UnregisterModelForTypeSignature(
                data_model.as_raw(),
                type_signature.as_raw(),
            )
        }
    }

    pub fn register_extension_for_type_signature(
        &self,
        type_signature: &DebugHostTypeSignature,
        data_model: &ModelObject,
    ) -> WinResult<()> {
        unsafe {
            self.0.RegisterExtensionForTypeSignature(
                type_signature.as_raw(),
                data_model.as_raw(),
            )
        }
    }

    pub fn unregister_extension_for_type_signature(
        &self,
        data_model: &ModelObject,
        type_signature: &DebugHostTypeSignature,
    ) -> WinResult<()> {
        unsafe {
            self.0.UnregisterExtensionForTypeSignature(
                data_model.as_raw(),
                type_signature.as_raw(),
            )
        }
    }

    pub fn create_metadata_store(
        &self,
        parent_store: Option<&KeyStore>,
    ) -> WinResult<KeyStore> {
        unsafe {
            Ok(self
                .0
                .CreateMetadataStore(parent_store.map(|x| x.as_raw()))?
                .into())
        }
    }

    pub fn get_root_namespace(&self) -> WinResult<ModelObject> {
        unsafe { Ok(self.0.GetRootNamespace()?.into()) }
    }

    pub fn register_named_model(
        &self,
        model_name: impl AsRef<WStr>,
        model_object: &ModelObject,
    ) -> WinResult<()> {
        unsafe {
            self.0
                .RegisterNamedModel(pcw!(model_name), model_object.as_raw())
        }
    }

    pub fn unregister_named_model(
        &self,
        model_name: impl AsRef<WStr>,
    ) -> WinResult<()> {
        unsafe { self.0.UnregisterNamedModel(pcw!(model_name)) }
    }

    pub fn acquire_named_model(
        &self,
        model_name: impl AsRef<WStr>,
    ) -> WinResult<ModelObject> {
        unsafe { Ok(self.0.AcquireNamedModel(pcw!(model_name))?.into()) }
    }
}

// IDataModelManager2
impl DataModelManager {
    pub fn acquire_sub_namespace(
        &self,
        model_name: impl AsRef<WStr>,
        sub_namespace_model_name: impl AsRef<WStr>,
        access_name: impl AsRef<WStr>,
        metadata: Option<&KeyStore>,
    ) -> WinResult<ModelObject> {
        unsafe {
            Ok(self
                .0
                .AcquireSubNamespace(
                    pcw!(model_name),
                    pcw!(sub_namespace_model_name),
                    pcw!(access_name),
                    metadata.as_ref().map(|x| x.as_raw()),
                )?
                .into())
        }
    }

    pub fn create_typed_intrinsic_object_ex<'a>(
        &self,
        context: impl Into<HostContextBy<'a>>,
        intrinsic_data: &Variant,
        r#type: &DebugHostType,
    ) -> WinResult<ModelObject> {
        unsafe {
            Ok(self
                .0
                .CreateTypedIntrinsicObjectEx(
                    context.into().as_raw(),
                    intrinsic_data.as_ref(),
                    r#type.as_raw(),
                )?
                .into())
        }
    }
}

// IDataModelManager3
impl DataModelManager {
    // AcquireFilteredSubNamespace

    // EnumerateNamedModels
}

// IDataModelManager4
impl DataModelManager {
    // CreateSyntheticObjectFromKeyStore
}