use crate::{
    Result, Rudof,
    api::shacl::ShaclOperations,
    formats::{DataReaderMode, InputSpec, ShaclFormat},
};

/// Builder for `load_shacl_schema` operation.
///
/// Provides a fluent interface for configuring and executing schema loading
/// operations with optional parameters.
pub struct LoadShaclShapesBuilder<'a> {
    rudof: &'a mut Rudof,
    schema: Option<&'a InputSpec>,
    schema_format: Option<&'a ShaclFormat>,
    base: Option<&'a str>,
    reader_mode: Option<&'a DataReaderMode>,
}

impl<'a> LoadShaclShapesBuilder<'a> {
    /// Creates a new builder instance.
    ///
    /// This is called internally by `Rudof::load_shacl_schema()` and should not
    /// be constructed directly.
    pub(crate) fn new(rudof: &'a mut Rudof) -> Self {
        Self {
            rudof,
            schema: None,
            schema_format: None,
            base: None,
            reader_mode: None,
        }
    }

    /// Sets the SHACL schema to load.
    ///
    /// # Arguments
    ///
    /// * `schema` - The input specification for the SHACL schema (e.g., file path, URL, or string content)
    pub fn with_shacl_schema(mut self, schema: &'a InputSpec) -> Self {
        self.schema = Some(schema);
        self
    }

    /// Sets the SHACL schema format.
    ///
    /// # Arguments
    ///
    /// * `schema_format` - The format to use when loading the schema
    pub fn with_shacl_schema_format(mut self, schema_format: &'a ShaclFormat) -> Self {
        self.schema_format = Some(schema_format);
        self
    }

    /// Sets the base IRI for resolving relative IRIs.
    ///
    /// # Arguments
    ///
    /// * `base` - The base IRI to use for resolution
    pub fn with_base(mut self, base: &'a str) -> Self {
        self.base = Some(base);
        self
    }

    /// Sets the reader mode for schema loading.
    ///
    /// # Arguments
    ///
    /// * `reader_mode` - The reading mode to apply during schema loading
    pub fn with_reader_mode(mut self, reader_mode: &'a DataReaderMode) -> Self {
        self.reader_mode = Some(reader_mode);
        self
    }

    /// Executes the schema loading operation with the configured parameters.
    pub fn execute(self) -> Result<()> {
        <Rudof as ShaclOperations>::load_shacl_schema(
            self.rudof,
            self.schema,
            self.schema_format,
            self.base,
            self.reader_mode,
        )
    }
}
