use std::path::Path;

use chrono::{DateTime, Utc};
use crate_meta::CrateMeta;
use kellnr_common::crate_data::CrateData;
use kellnr_common::crate_overview::CrateOverview;
use kellnr_common::cratesio_prefetch_msg::CratesioPrefetchMsg;
use kellnr_common::index_metadata::IndexMetadata;
use kellnr_common::normalized_name::NormalizedName;
use kellnr_common::original_name::OriginalName;
use kellnr_common::prefetch::Prefetch;
use kellnr_common::publish_metadata::PublishMetadata;
use kellnr_common::version::Version;
use kellnr_common::webhook::{Webhook, WebhookEvent, WebhookQueue};
use sea_orm::prelude::async_trait::async_trait;
use serde::{Deserialize, Serialize};

use crate::error::DbError;
use crate::{AuthToken, CrateSummary, DocQueueEntry, Group, User, crate_meta};

pub type DbResult<T> = Result<T, DbError>;

#[derive(Debug, PartialEq, Eq)]
pub enum PrefetchState {
    UpToDate,
    NeedsUpdate(Prefetch),
    NotFound,
}

/// Data stored during `OAuth2` authentication flow for CSRF/PKCE verification
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct OAuth2StateData {
    pub state: String,
    pub pkce_verifier: String,
    pub nonce: String,
}

/// Information about an individual toolchain component (e.g., rustc, cargo)
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, utoipa::ToSchema)]
pub struct ToolchainComponentInfo {
    /// Component name (e.g., "rustc", "cargo", "rust-std-x86_64-unknown-linux-gnu")
    pub name: String,
    /// Path to the stored component archive
    pub storage_path: String,
    /// SHA256 hash of the component archive
    pub hash: String,
    /// Component archive size in bytes
    pub size: i64,
}

impl From<kellnr_entity::toolchain_component::Model> for ToolchainComponentInfo {
    fn from(c: kellnr_entity::toolchain_component::Model) -> Self {
        Self {
            name: c.name,
            storage_path: c.storage_path,
            hash: c.hash,
            size: c.size,
        }
    }
}

/// Toolchain target information (e.g., a specific archive for a target triple)
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, utoipa::ToSchema)]
pub struct ToolchainTargetInfo {
    /// Target ID
    pub id: i64,
    /// Target triple (e.g., "x86_64-unknown-linux-gnu")
    pub target: String,
    /// Path to the stored archive
    pub storage_path: String,
    /// SHA256 hash of the archive
    pub hash: String,
    /// Archive size in bytes
    pub size: i64,
    /// Processing status: "processing", "ready", or "failed"
    pub status: String,
    /// Individual components extracted from the combined archive
    pub components: Vec<ToolchainComponentInfo>,
}

/// Toolchain with all its targets
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, utoipa::ToSchema)]
pub struct ToolchainWithTargets {
    /// Toolchain ID
    pub id: i64,
    /// Toolchain name (e.g., "rust")
    pub name: String,
    /// Toolchain version (e.g., "1.75.0")
    pub version: String,
    /// Release date
    pub date: String,
    /// Channel (e.g., "stable", "beta", "nightly")
    pub channel: Option<String>,
    /// Creation timestamp
    pub created: String,
    /// Available targets for this toolchain
    pub targets: Vec<ToolchainTargetInfo>,
}

/// Channel information (e.g., "stable" -> "1.75.0")
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, utoipa::ToSchema)]
pub struct ChannelInfo {
    /// Channel name (e.g., "stable", "beta", "nightly")
    pub name: String,
    /// Toolchain version pointed to by this channel
    pub version: String,
    /// Release date
    pub date: String,
}

#[async_trait]
pub trait DbProvider: Send + Sync {
    async fn get_last_updated_crate(&self) -> DbResult<Option<(OriginalName, Version)>>;
    async fn authenticate_user(&self, name: &str, pwd: &str) -> DbResult<User>;
    async fn increase_download_counter(
        &self,
        crate_name: &NormalizedName,
        crate_version: &Version,
    ) -> DbResult<()>;
    async fn increase_cached_download_counter(
        &self,
        crate_name: &NormalizedName,
        crate_version: &Version,
    ) -> DbResult<()>;
    async fn increase_download_counter_by(
        &self,
        crate_name: &NormalizedName,
        crate_version: &Version,
        count: u64,
    ) -> DbResult<()>;
    async fn increase_cached_download_counter_by(
        &self,
        crate_name: &NormalizedName,
        crate_version: &Version,
        count: u64,
    ) -> DbResult<()>;
    async fn validate_session(&self, session_token: &str) -> DbResult<(String, bool)>;
    async fn add_session_token(&self, name: &str, session_token: &str) -> DbResult<()>;
    async fn add_crate_user(&self, crate_name: &NormalizedName, user: &str) -> DbResult<()>;
    async fn add_owner(&self, crate_name: &NormalizedName, owner: &str) -> DbResult<()>;
    async fn is_download_restricted(&self, crate_name: &NormalizedName) -> DbResult<bool>;
    async fn change_download_restricted(
        &self,
        crate_name: &NormalizedName,
        restricted: bool,
    ) -> DbResult<()>;
    async fn is_crate_user(&self, crate_name: &NormalizedName, user: &str) -> DbResult<bool>;
    async fn is_owner(&self, crate_name: &NormalizedName, user: &str) -> DbResult<bool>;
    async fn get_crate_id(&self, crate_name: &NormalizedName) -> DbResult<Option<i64>>;
    async fn get_crate_owners(&self, crate_name: &NormalizedName) -> DbResult<Vec<User>>;
    async fn get_crate_users(&self, crate_name: &NormalizedName) -> DbResult<Vec<User>>;
    async fn get_crate_versions(&self, crate_name: &NormalizedName) -> DbResult<Vec<Version>>;
    async fn delete_session_token(&self, session_token: &str) -> DbResult<()>;
    async fn delete_user(&self, user_name: &str) -> DbResult<()>;
    async fn change_pwd(&self, user_name: &str, new_pwd: &str) -> DbResult<()>;
    async fn change_read_only_state(&self, user_name: &str, state: bool) -> DbResult<()>;
    async fn change_admin_state(&self, user_name: &str, state: bool) -> DbResult<()>;
    async fn crate_version_exists(&self, crate_id: i64, version: &str) -> DbResult<bool>;
    async fn get_max_version_from_id(&self, crate_id: i64) -> DbResult<Version>;
    async fn get_max_version_from_name(&self, crate_name: &NormalizedName) -> DbResult<Version>;
    async fn update_max_version(&self, crate_id: i64, version: &Version) -> DbResult<()>;
    async fn add_auth_token(&self, name: &str, token: &str, user: &str) -> DbResult<()>;
    async fn get_user_from_token(&self, token: &str) -> DbResult<User>;
    async fn get_user(&self, name: &str) -> DbResult<User>;
    async fn get_auth_tokens(&self, user_name: &str) -> DbResult<Vec<AuthToken>>;
    async fn delete_auth_token(&self, id: i32) -> DbResult<()>;
    async fn delete_owner(&self, crate_name: &str, owner: &str) -> DbResult<()>;
    async fn delete_crate_user(&self, crate_name: &NormalizedName, user: &str) -> DbResult<()>;
    async fn add_user(
        &self,
        name: &str,
        pwd: &str,
        salt: &str,
        is_admin: bool,
        is_read_only: bool,
    ) -> DbResult<()>;
    async fn get_users(&self) -> DbResult<Vec<User>>;
    async fn add_group(&self, name: &str) -> DbResult<()>;
    async fn get_group(&self, name: &str) -> DbResult<Group>;
    async fn get_groups(&self) -> DbResult<Vec<Group>>;
    async fn delete_group(&self, name: &str) -> DbResult<()>;
    async fn add_group_user(&self, group_name: &str, user: &str) -> DbResult<()>;
    async fn delete_group_user(&self, group_name: &str, user: &str) -> DbResult<()>;
    async fn get_group_users(&self, group_name: &str) -> DbResult<Vec<User>>;
    async fn is_group_user(&self, group_name: &str, group: &str) -> DbResult<bool>;
    async fn add_crate_group(&self, crate_name: &NormalizedName, group: &str) -> DbResult<()>;
    async fn delete_crate_group(&self, crate_name: &NormalizedName, group: &str) -> DbResult<()>;
    async fn get_crate_groups(&self, crate_name: &NormalizedName) -> DbResult<Vec<Group>>;
    async fn is_crate_group(&self, crate_name: &NormalizedName, group: &str) -> DbResult<bool>;
    async fn is_crate_group_user(&self, crate_name: &NormalizedName, user: &str) -> DbResult<bool>;
    async fn get_total_unique_crates(&self) -> DbResult<u64>;
    async fn get_total_crate_versions(&self) -> DbResult<u64>;
    async fn get_total_downloads(&self) -> DbResult<u64>;
    async fn get_top_crates_downloads(&self, top: u64) -> DbResult<Vec<(String, u64)>>;
    async fn get_total_unique_cached_crates(&self) -> DbResult<u64>;
    async fn get_total_cached_crate_versions(&self) -> DbResult<u64>;
    async fn get_total_cached_downloads(&self) -> DbResult<u64>;
    async fn get_crate_summaries(&self) -> DbResult<Vec<CrateSummary>>;
    async fn add_doc_queue(
        &self,
        krate: &NormalizedName,
        version: &Version,
        path: &Path,
    ) -> DbResult<()>;
    async fn delete_doc_queue(&self, id: i64) -> DbResult<()>;
    async fn get_doc_queue(&self) -> DbResult<Vec<DocQueueEntry>>;
    async fn delete_crate(&self, krate: &NormalizedName, version: &Version) -> DbResult<()>;
    async fn get_crate_meta_list(&self, crate_name: &NormalizedName) -> DbResult<Vec<CrateMeta>>;
    async fn update_last_updated(&self, id: i64, last_updated: &DateTime<Utc>) -> DbResult<()>;
    async fn search_in_crate_name(
        &self,
        contains: &str,
        cache: bool,
    ) -> DbResult<Vec<CrateOverview>>;
    async fn get_crate_overview_list(
        &self,
        limit: u64,
        offset: u64,
        cache: bool,
    ) -> DbResult<Vec<CrateOverview>>;
    async fn get_crate_data(&self, crate_name: &NormalizedName) -> DbResult<CrateData>;
    async fn add_empty_crate(&self, name: &str, created: &DateTime<Utc>) -> DbResult<i64>;
    async fn add_crate(
        &self,
        pub_metadata: &PublishMetadata,
        cksum: &str,
        created: &DateTime<Utc>,
        owner: &str,
    ) -> DbResult<i64>;
    async fn update_docs_link(
        &self,
        crate_name: &NormalizedName,
        version: &Version,
        docs_link: &str,
    ) -> DbResult<()>;
    async fn add_crate_metadata(
        &self,
        pub_metadata: &PublishMetadata,
        created: &str,
        crate_id: i64,
    ) -> DbResult<()>;
    async fn get_prefetch_data(&self, crate_name: &str) -> DbResult<Prefetch>;
    async fn is_cratesio_cache_up_to_date(
        &self,
        crate_name: &NormalizedName,
        if_none_match: Option<String>,
        if_modified_since: Option<String>,
    ) -> DbResult<PrefetchState>;
    async fn add_cratesio_prefetch_data(
        &self,
        crate_name: &OriginalName,
        etag: &str,
        last_modified: &str,
        description: Option<String>,
        indices: &[IndexMetadata],
    ) -> DbResult<Prefetch>;
    async fn get_cratesio_index_update_list(&self) -> DbResult<Vec<CratesioPrefetchMsg>>;
    async fn unyank_crate(&self, crate_name: &NormalizedName, version: &Version) -> DbResult<()>;
    async fn yank_crate(&self, crate_name: &NormalizedName, version: &Version) -> DbResult<()>;
    async fn register_webhook(&self, webhook: Webhook) -> DbResult<String>;
    async fn delete_webhook(&self, id: &str) -> DbResult<()>;
    async fn get_webhook(&self, id: &str) -> DbResult<Webhook>;
    async fn get_all_webhooks(&self) -> DbResult<Vec<Webhook>>;
    /// Creates a new webhook queue entry for each register webhook
    /// matching the given event. `Next_attempt` is set to current time,
    ///  in order to trigger immediate dispatch.
    async fn add_webhook_queue(
        &self,
        event: WebhookEvent,
        payload: serde_json::Value,
    ) -> DbResult<()>;
    /// Extracts webhook queue entries with `next_attempt` at or earlier than provided timestamp.
    async fn get_pending_webhook_queue_entries(
        &self,
        timestamp: DateTime<Utc>,
    ) -> DbResult<Vec<WebhookQueue>>;
    async fn update_webhook_queue(
        &self,
        id: &str,
        last_attempt: DateTime<Utc>,
        next_attempt: DateTime<Utc>,
    ) -> DbResult<()>;
    async fn delete_webhook_queue(&self, id: &str) -> DbResult<()>;

    // `OAuth2` identity methods
    /// Look up a user by their `OAuth2` identity (issuer + subject)
    async fn get_user_by_oauth2_identity(
        &self,
        issuer: &str,
        subject: &str,
    ) -> DbResult<Option<User>>;

    /// Create a new user from `OAuth2` authentication and link their identity
    async fn create_oauth2_user(
        &self,
        username: &str,
        issuer: &str,
        subject: &str,
        email: Option<String>,
        is_admin: bool,
        is_read_only: bool,
    ) -> DbResult<User>;

    /// Link an `OAuth2` identity to an existing user
    async fn link_oauth2_identity(
        &self,
        user_id: i64,
        issuer: &str,
        subject: &str,
        email: Option<String>,
    ) -> DbResult<()>;

    // `OAuth2` state methods (CSRF/PKCE during auth flow)
    /// Store `OAuth2` state for CSRF/PKCE verification during auth flow
    async fn store_oauth2_state(
        &self,
        state: &str,
        pkce_verifier: &str,
        nonce: &str,
    ) -> DbResult<()>;

    /// Retrieve and delete `OAuth2` state (single use)
    async fn get_and_delete_oauth2_state(&self, state: &str) -> DbResult<Option<OAuth2StateData>>;

    /// Clean up expired `OAuth2` states (older than 10 minutes)
    async fn cleanup_expired_oauth2_states(&self) -> DbResult<u64>;

    /// Check if username is available (for `OAuth2` auto-provisioning)
    async fn is_username_available(&self, username: &str) -> DbResult<bool>;

    // Toolchain distribution methods
    /// Add a new toolchain release
    async fn add_toolchain(
        &self,
        name: &str,
        version: &str,
        date: &str,
        channel: Option<String>,
    ) -> DbResult<i64>;

    /// Add a target archive to an existing toolchain
    async fn add_toolchain_target(
        &self,
        toolchain_id: i64,
        target: &str,
        storage_path: &str,
        hash: &str,
        size: i64,
    ) -> DbResult<i64>;

    /// Add a component to a toolchain target
    async fn add_toolchain_component(
        &self,
        target_id: i64,
        name: &str,
        storage_path: &str,
        hash: &str,
        size: i64,
    ) -> DbResult<()>;

    /// Update the processing status of a toolchain target
    async fn set_target_status(&self, target_id: i64, status: &str) -> DbResult<()>;

    /// Get a toolchain by its channel (e.g., "stable", "nightly")
    async fn get_toolchain_by_channel(
        &self,
        channel: &str,
    ) -> DbResult<Option<ToolchainWithTargets>>;

    /// Get a toolchain by name and version
    async fn get_toolchain_by_version(
        &self,
        name: &str,
        version: &str,
    ) -> DbResult<Option<ToolchainWithTargets>>;

    /// List all toolchains
    async fn list_toolchains(&self) -> DbResult<Vec<ToolchainWithTargets>>;

    /// Delete a toolchain and all its targets
    async fn delete_toolchain(&self, name: &str, version: &str) -> DbResult<()>;

    /// Delete a specific toolchain target
    async fn delete_toolchain_target(
        &self,
        name: &str,
        version: &str,
        target: &str,
    ) -> DbResult<()>;

    /// Set a channel to point to a specific toolchain version
    async fn set_channel(&self, channel: &str, name: &str, version: &str) -> DbResult<()>;

    /// Get all channels with their current versions
    async fn get_channels(&self) -> DbResult<Vec<ChannelInfo>>;
}

pub mod mock {
    use chrono::DateTime;
    use mockall::predicate::*;
    use mockall::*;

    use super::*;

    mock! {
          pub Db {}

        #[async_trait]
        impl DbProvider for Db {

            async fn get_last_updated_crate(&self) -> DbResult<Option<(OriginalName, Version)>> {
                unimplemented!()
            }

            async fn authenticate_user(&self, _name: &str, _pwd: &str) -> DbResult<User> {
                unimplemented!()
            }

            async fn increase_download_counter(
                &self,
                _crate_name: &NormalizedName,
                _crate_version: &Version,
            ) -> DbResult<()> {
                unimplemented!()
            }

            async fn increase_cached_download_counter(
                &self,
                _crate_name: &NormalizedName,
                _crate_version: &Version,
            ) -> DbResult<()> {
                unimplemented!()
            }

            async fn increase_download_counter_by(
                &self,
                _crate_name: &NormalizedName,
                _crate_version: &Version,
                _count: u64,
            ) -> DbResult<()> {
                unimplemented!()
            }

            async fn increase_cached_download_counter_by(
                &self,
                _crate_name: &NormalizedName,
                _crate_version: &Version,
                _count: u64,
            ) -> DbResult<()> {
                unimplemented!()
            }

            async fn validate_session(&self, _session_token: &str) -> DbResult<(String, bool)> {
                unimplemented!()
            }

            async fn add_session_token(&self, _name: &str, _session_token: &str) -> DbResult<()> {
                unimplemented!()
            }

            async fn add_crate_user(&self, crate_name: &NormalizedName, user: &str) -> DbResult<()> {
                unimplemented!()
            }

            async fn add_owner(&self, _crate_name: &NormalizedName, _owner: &str) -> DbResult<()> {
                unimplemented!()
            }

            async fn is_download_restricted(&self, crate_name: &NormalizedName) -> DbResult<bool> {
                unimplemented!()
            }

            async fn change_download_restricted(
                &self,
                crate_name: &NormalizedName,
                restricted: bool,
            ) -> DbResult<()> {
                unimplemented!()
            }

            async fn is_crate_user(&self, _crate_name: &NormalizedName, _user: &str) -> DbResult<bool> {
                unimplemented!()
            }

            async fn is_owner(&self, _crate_name: &NormalizedName, _user: &str) -> DbResult<bool> {
                unimplemented!()
            }

            async fn get_crate_id(&self, _crate_name: &NormalizedName) -> DbResult<Option<i64>> {
                unimplemented!()
            }

            async fn get_crate_owners(&self, _crate_name: &NormalizedName) -> DbResult<Vec<User>> {
                unimplemented!()
            }

            async fn get_crate_users(&self, _crate_name: &NormalizedName) -> DbResult<Vec<User>> {
                unimplemented!()
            }

            async fn get_crate_versions(&self, _crate_name: &NormalizedName) -> DbResult<Vec<Version>> {
                unimplemented!()
            }

            async fn delete_session_token(&self, _session_token: &str) -> DbResult<()> {
                unimplemented!()
            }

            async fn delete_user(&self, _user_name: &str) -> DbResult<()> {
                unimplemented!()
            }

            async fn change_pwd(&self, _user_name: &str, _new_pwd: &str) -> DbResult<()> {
                unimplemented!()
            }

            async fn change_read_only_state(&self, _user_name: &str, _state: bool) -> DbResult<()> {
                unimplemented!()
            }

            async fn change_admin_state(&self, _user_name: &str, _state: bool) -> DbResult<()> {
                unimplemented!()
            }

            async fn crate_version_exists(&self, _crate_id: i64, _version: &str) -> DbResult<bool> {
                unimplemented!()
            }

            async fn get_max_version_from_id(&self, crate_id: i64) -> DbResult<Version>  {
                unimplemented!()
            }

            async fn get_max_version_from_name(&self, crate_name: &NormalizedName) -> DbResult<Version> {
                unimplemented!()
            }

            async fn update_max_version(&self, crate_id: i64, version: &Version) -> DbResult<()> {
                unimplemented!()
            }

            async fn add_auth_token(&self, _name: &str, _token: &str, _user: &str) -> DbResult<()> {
                unimplemented!()
            }

            async fn get_user_from_token(&self, _token: &str) -> DbResult<User> {
                unimplemented!()
            }

            async fn get_user(&self, _name: &str) -> DbResult<User> {
                unimplemented!()
            }

            async fn get_auth_tokens(&self, _user_name: &str) -> DbResult<Vec<AuthToken>> {
                unimplemented!()
            }

            async fn delete_auth_token(&self, _id: i32) -> DbResult<()> {
                unimplemented!()
            }

            async fn delete_owner(&self, _crate_name: &str, _owner: &str) -> DbResult<()> {
                unimplemented!()
            }

            async fn delete_crate_user(&self, crate_name: &NormalizedName, user: &str) -> DbResult<()>{
                unimplemented!()
            }

            async fn add_user(&self, _name: &str, _pwd: &str, _salt: &str, _is_admin: bool, _is_read_only: bool) -> DbResult<()> {
                unimplemented!()
            }

            async fn get_users(&self) -> DbResult<Vec<User>> {
                unimplemented!()
            }

            async fn get_total_unique_crates(&self) -> DbResult<u64> {
                unimplemented!()
            }

            async fn get_total_crate_versions(&self) -> DbResult<u64> {
                unimplemented!()
            }

            async fn get_top_crates_downloads(&self, _top: u64) -> DbResult<Vec<(String, u64)>> {
                unimplemented!()
            }

            async fn get_total_unique_cached_crates(&self) -> DbResult<u64> {
                unimplemented!()
            }

            async fn get_total_cached_crate_versions(&self) -> DbResult<u64> {
                unimplemented!()
            }

            async fn get_total_cached_downloads(&self) -> DbResult<u64> {
                unimplemented!()
            }

            async fn get_crate_summaries(&self) -> DbResult<Vec<CrateSummary >> {
                unimplemented!()
            }

                async fn add_doc_queue(&self, krate: &NormalizedName, version: &Version, path: &Path) -> DbResult<()>{
                    unimplemented!()
                }

            async fn delete_doc_queue(&self, id: i64) -> DbResult<()>{
                    unimplemented!()
                }

            async fn get_doc_queue(&self) -> DbResult<Vec<DocQueueEntry>> {
                unimplemented!()
            }

            async fn delete_crate(&self, krate: &NormalizedName, version: &Version) -> DbResult<()> {
                unimplemented!()
            }

            async fn get_total_downloads(&self) -> DbResult<u64>{
                unimplemented!()
            }

            async fn get_crate_meta_list(&self, crate_name: &NormalizedName) -> DbResult<Vec<CrateMeta>>{
                unimplemented!()
            }

            async fn update_last_updated(&self, id: i64, last_updated: &DateTime<Utc>) -> DbResult<()>{
                unimplemented!()
            }

            async fn search_in_crate_name(&self, contains: &str, cache: bool) -> DbResult<Vec<CrateOverview>> {
                unimplemented!()
            }

            async fn get_crate_overview_list(&self, limit: u64, offset: u64, cache: bool) -> DbResult<Vec<CrateOverview >> {
                unimplemented!()
            }

            async fn get_crate_data(&self, crate_name: &NormalizedName) -> DbResult<CrateData> {
                unimplemented!()
            }

            async fn add_empty_crate(&self, name: &str, created: &DateTime<Utc>) -> DbResult<i64> {
                unimplemented!()
            }

            async fn add_crate(&self, pub_metadata: &PublishMetadata, sha256: &str, created: &DateTime<Utc>, owner: &str) -> DbResult<i64> {
                unimplemented!()
            }

            async fn update_docs_link(&self, crate_name: &NormalizedName, version: &Version, docs_link: &str) -> DbResult<()> {
                unimplemented!()
            }

            async fn add_crate_metadata(&self, pub_metadata: &PublishMetadata, created: &str, crate_id: i64,) -> DbResult<()> {
                unimplemented!()
            }

            async fn get_prefetch_data(&self, crate_name: &str) -> DbResult<Prefetch> {
                unimplemented!()
            }

            async fn is_cratesio_cache_up_to_date(&self, crate_name: &NormalizedName, etag: Option<String>, last_modified: Option<String>) -> DbResult<PrefetchState> {
                unimplemented!()
            }

            async fn add_cratesio_prefetch_data(
                &self,
                crate_name: &OriginalName,
                etag: &str,
                last_modified: &str,
                description: Option<String>,
                indices: &[IndexMetadata],
            ) -> DbResult<Prefetch> {
                unimplemented!()
            }

            async fn get_cratesio_index_update_list(&self) -> DbResult<Vec<CratesioPrefetchMsg>> {
                unimplemented!()
            }

            async fn unyank_crate(&self, crate_name: &NormalizedName, version: &Version) -> DbResult<()> {
                unimplemented!()
            }

            async fn yank_crate(&self, crate_name: &NormalizedName, version: &Version) -> DbResult<()> {
                unimplemented!()
            }

            async fn add_group(&self, name: &str) -> DbResult<()> {
                        unimplemented!()
            }
            async fn get_group(&self, name: &str) -> DbResult<Group>{
                        unimplemented!()
            }
            async fn get_groups(&self) -> DbResult<Vec<Group>>{
                        unimplemented!()
            }
            async fn delete_group(&self, name: &str) -> DbResult<()>{
                        unimplemented!()
            }
            async fn add_group_user(&self, group_name: &str, user: &str) -> DbResult<()>{
                        unimplemented!()
            }
            async fn delete_group_user(&self, group_name: &str, user: &str) -> DbResult<()>{
                        unimplemented!()
            }
            async fn get_group_users(&self, group_name: &str) -> DbResult<Vec<User>> {
                unimplemented!()
            }
            async fn is_group_user(&self, group_name: &str, user: &str) -> DbResult<bool> {
                unimplemented!()
            }

            async fn add_crate_group(&self, crate_name: &NormalizedName, group: &str) -> DbResult<()>{
                unimplemented!()
            }
            async fn delete_crate_group(&self, crate_name: &NormalizedName, group: &str) -> DbResult<()>{
                unimplemented!()
            }
            async fn get_crate_groups(&self, crate_name: &NormalizedName) -> DbResult<Vec<Group>>{
                unimplemented!()
            }
            async fn is_crate_group(&self, crate_name: &NormalizedName, group: &str) -> DbResult<bool>{
                unimplemented!()
            }

            async fn is_crate_group_user(&self, crate_name: &NormalizedName, user: &str) -> DbResult<bool>{
                unimplemented!()
            }

            async fn register_webhook(
                &self,
                webhook: Webhook
            ) -> DbResult<String> {
                unimplemented!()
            }
            async fn delete_webhook(&self, id: &str) -> DbResult<()> {
                unimplemented!()
            }
            async fn get_webhook(&self, id: &str) -> DbResult<Webhook> {
                unimplemented!()
            }
            async fn get_all_webhooks(&self) -> DbResult<Vec<Webhook>> {
                unimplemented!()
            }
            async fn add_webhook_queue(&self, event: WebhookEvent, payload: serde_json::Value) -> DbResult<()> {
                unimplemented!()
            }
            async fn get_pending_webhook_queue_entries(&self, timestamp: DateTime<Utc>) -> DbResult<Vec<WebhookQueue>> {
                unimplemented!()
            }
            async fn update_webhook_queue(&self, id: &str, last_attempt: DateTime<Utc>, next_attempt: DateTime<Utc>) -> DbResult<()> {
                unimplemented!()
            }
            async fn delete_webhook_queue(&self, id: &str) -> DbResult<()> {
                unimplemented!()
            }

            async fn get_user_by_oauth2_identity(
                &self,
                issuer: &str,
                subject: &str,
            ) -> DbResult<Option<User>> {
                unimplemented!()
            }

            async fn create_oauth2_user(
                &self,
                username: &str,
                issuer: &str,
                subject: &str,
                email: Option<String>,
                is_admin: bool,
                is_read_only: bool,
            ) -> DbResult<User> {
                unimplemented!()
            }

            async fn link_oauth2_identity(
                &self,
                user_id: i64,
                issuer: &str,
                subject: &str,
                email: Option<String>,
            ) -> DbResult<()> {
                unimplemented!()
            }

            async fn store_oauth2_state(
                &self,
                state: &str,
                pkce_verifier: &str,
                nonce: &str,
            ) -> DbResult<()> {
                unimplemented!()
            }

            async fn get_and_delete_oauth2_state(
                &self,
                state: &str,
            ) -> DbResult<Option<OAuth2StateData>> {
                unimplemented!()
            }

            async fn cleanup_expired_oauth2_states(&self) -> DbResult<u64> {
                unimplemented!()
            }

            async fn is_username_available(&self, username: &str) -> DbResult<bool> {
                unimplemented!()
            }

            async fn add_toolchain(
                &self,
                name: &str,
                version: &str,
                date: &str,
                channel: Option<String>,
            ) -> DbResult<i64> {
                unimplemented!()
            }

            async fn add_toolchain_target(
                &self,
                toolchain_id: i64,
                target: &str,
                storage_path: &str,
                hash: &str,
                size: i64,
            ) -> DbResult<i64> {
                unimplemented!()
            }

            async fn add_toolchain_component(
                &self,
                target_id: i64,
                name: &str,
                storage_path: &str,
                hash: &str,
                size: i64,
            ) -> DbResult<()> {
                unimplemented!()
            }

            async fn set_target_status(&self, target_id: i64, status: &str) -> DbResult<()> {
                unimplemented!()
            }

            async fn get_toolchain_by_channel(&self, channel: &str) -> DbResult<Option<ToolchainWithTargets>> {
                unimplemented!()
            }

            async fn get_toolchain_by_version(
                &self,
                name: &str,
                version: &str,
            ) -> DbResult<Option<ToolchainWithTargets>> {
                unimplemented!()
            }

            async fn list_toolchains(&self) -> DbResult<Vec<ToolchainWithTargets>> {
                unimplemented!()
            }

            async fn delete_toolchain(&self, name: &str, version: &str) -> DbResult<()> {
                unimplemented!()
            }

            async fn delete_toolchain_target(
                &self,
                name: &str,
                version: &str,
                target: &str,
            ) -> DbResult<()> {
                unimplemented!()
            }

            async fn set_channel(&self, channel: &str, name: &str, version: &str) -> DbResult<()> {
                unimplemented!()
            }

            async fn get_channels(&self) -> DbResult<Vec<ChannelInfo>> {
                unimplemented!()
            }
        }
    }
}
