// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

// expose the opendal rust core as `core`.
// We will use `ocore::Xxx` to represents all types from opendal rust core.
pub use ::opendal as ocore;
use pyo3::prelude::*;

mod capability;
pub use capability::*;
mod layers;
pub use layers::*;
mod lister;
pub use lister::*;
mod metadata;
pub use metadata::*;
mod operator;
pub use operator::*;
mod file;
pub use file::*;
mod utils;
pub use utils::*;
mod errors;
pub use errors::*;
mod options;
pub use options::*;
mod services;
pub use services::*;

// The `opendal` Python package is a mixed Python/native layout: the public
// package is the hand-written `python/opendal/` (with its own `__init__.py`),
// and this native module is built as the private submodule `opendal._opendal`
// (`module-name` in pyproject.toml). The `#[pymodule] mod` name must therefore
// be `_opendal` to match the compiled `opendal/_opendal.*.so` (its `PyInit`
// symbol); `__init__.py` imports and re-exports from it as the public API.
#[pymodule(gil_used = false)]
mod _opendal {
    use pyo3::prelude::*;

    #[pymodule]
    mod operator {
        #[pymodule_export]
        use crate::{AsyncOperator, Operator};
    }

    #[pymodule]
    mod file {
        #[pymodule_export]
        use crate::{AsyncFile, File};
    }

    #[pymodule]
    mod capability {
        #[pymodule_export]
        use crate::Capability;
    }

    #[pymodule]
    mod services {
        #[pymodule_export]
        use crate::Scheme;
    }

    #[pymodule]
    mod layers {
        #[pymodule_export]
        use crate::{
            CapabilityOverrideLayer, ConcurrentLimitLayer, Layer, MimeGuessLayer, RetryLayer,
        };
    }

    #[pymodule]
    mod types {
        #[pymodule_export]
        use crate::{Entry, EntryMode, Metadata, PresignedRequest};
    }

    // Exceptions are `PyErr` subtypes, not `#[pyclass]`es, so they are added
    // procedurally rather than via `#[pymodule_export]`.
    #[pymodule]
    mod exceptions {
        #[pymodule_init]
        fn init(m: &pyo3::Bound<'_, pyo3::types::PyModule>) -> pyo3::PyResult<()> {
            use pyo3::prelude::*;

            use crate::{
                AlreadyExists, ConditionNotMatch, ConfigInvalid, Error, IsADirectory, IsSameFile,
                NotADirectory, NotFound, PermissionDenied, RangeNotSatisfied, RateLimited,
                Unexpected, Unsupported, add_exceptions,
            };

            add_exceptions!(
                m,
                [
                    Error,
                    Unexpected,
                    Unsupported,
                    ConfigInvalid,
                    NotFound,
                    PermissionDenied,
                    IsADirectory,
                    NotADirectory,
                    AlreadyExists,
                    IsSameFile,
                    ConditionNotMatch,
                    RateLimited,
                    RangeNotSatisfied,
                ]
            )
        }
    }

    // Option types live directly on the top-level `opendal` module.
    #[pymodule_export]
    use crate::{DeleteOptions, ListOptions, ReadOptions, StatOptions, WriteOptions};

    #[pymodule_export]
    #[allow(non_upper_case_globals)]
    pub const __version__: &str = env!("CARGO_PKG_VERSION");

    // Make the submodules importable as `opendal.<name>`.
    #[pymodule_init]
    fn init(m: &Bound<'_, PyModule>) -> PyResult<()> {
        crate::register_submodules(m, "opendal")
    }
}
