// Copyright 2024 RustFS Team
//
// Licensed 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.

use super::*;

pub fn register_table_catalog_route(r: &mut S3Router<AdminOperation>) -> std::io::Result<()> {
    for prefix in [TABLE_CATALOG_PREFIX, TABLE_CATALOG_COMPAT_PREFIX] {
        register_table_catalog_prefix_routes(r, prefix)?;
    }

    Ok(())
}

fn register_table_catalog_prefix_routes(r: &mut S3Router<AdminOperation>, prefix: &str) -> std::io::Result<()> {
    r.insert(Method::GET, format!("{prefix}/config").as_str(), AdminOperation(&GET_CONFIG_HANDLER))?;
    r.insert(
        Method::PUT,
        format!("{prefix}/buckets/{{warehouse}}").as_str(),
        AdminOperation(&ENABLE_TABLE_BUCKET_HANDLER),
    )?;
    r.insert(
        Method::GET,
        format!("{prefix}/buckets/{{warehouse}}").as_str(),
        AdminOperation(&GET_TABLE_BUCKET_HANDLER),
    )?;
    r.insert(
        Method::GET,
        format!("{prefix}/{{warehouse}}/catalog/migration").as_str(),
        AdminOperation(&GET_TABLE_CATALOG_MIGRATION_HANDLER),
    )?;
    r.insert(
        Method::POST,
        format!("{prefix}/{{warehouse}}/catalog/migration").as_str(),
        AdminOperation(&MATERIALIZE_TABLE_CATALOG_MIGRATION_HANDLER),
    )?;
    r.insert(
        Method::DELETE,
        format!("{prefix}/{{warehouse}}/catalog/migration").as_str(),
        AdminOperation(&CANCEL_TABLE_CATALOG_MIGRATION_HANDLER),
    )?;
    r.insert(
        Method::GET,
        format!("{prefix}/{{warehouse}}/namespaces").as_str(),
        AdminOperation(&LIST_NAMESPACES_HANDLER),
    )?;
    r.insert(
        Method::POST,
        format!("{prefix}/{{warehouse}}/namespaces").as_str(),
        AdminOperation(&CREATE_NAMESPACE_HANDLER),
    )?;
    r.insert(
        Method::GET,
        format!("{prefix}/{{warehouse}}/namespaces/{{namespace}}").as_str(),
        AdminOperation(&GET_NAMESPACE_HANDLER),
    )?;
    r.insert(
        Method::HEAD,
        format!("{prefix}/{{warehouse}}/namespaces/{{namespace}}").as_str(),
        AdminOperation(&NAMESPACE_EXISTS_HANDLER),
    )?;
    r.insert(
        Method::POST,
        format!("{prefix}/{{warehouse}}/namespaces/{{namespace}}/properties").as_str(),
        AdminOperation(&UPDATE_NAMESPACE_PROPERTIES_HANDLER),
    )?;
    r.insert(
        Method::DELETE,
        format!("{prefix}/{{warehouse}}/namespaces/{{namespace}}").as_str(),
        AdminOperation(&DROP_NAMESPACE_HANDLER),
    )?;
    r.insert(
        Method::POST,
        format!("{prefix}/{{warehouse}}/tables/rename").as_str(),
        AdminOperation(&RENAME_TABLE_HANDLER),
    )?;
    r.insert(
        Method::GET,
        format!("{prefix}/{{warehouse}}/namespaces/{{namespace}}/tables").as_str(),
        AdminOperation(&LIST_TABLES_HANDLER),
    )?;
    r.insert(
        Method::POST,
        format!("{prefix}/{{warehouse}}/namespaces/{{namespace}}/tables").as_str(),
        AdminOperation(&CREATE_TABLE_HANDLER),
    )?;
    r.insert(
        Method::POST,
        format!("{prefix}/{{warehouse}}/namespaces/{{namespace}}/register").as_str(),
        AdminOperation(&REGISTER_TABLE_HANDLER),
    )?;
    r.insert(
        Method::GET,
        format!("{prefix}/{{warehouse}}/namespaces/{{namespace}}/views").as_str(),
        AdminOperation(&LIST_VIEWS_HANDLER),
    )?;
    r.insert(
        Method::POST,
        format!("{prefix}/{{warehouse}}/namespaces/{{namespace}}/views").as_str(),
        AdminOperation(&CREATE_VIEW_HANDLER),
    )?;
    r.insert(
        Method::GET,
        format!("{prefix}/{{warehouse}}/namespaces/{{namespace}}/tables/{{table}}").as_str(),
        AdminOperation(&LOAD_TABLE_HANDLER),
    )?;
    r.insert(
        Method::HEAD,
        format!("{prefix}/{{warehouse}}/namespaces/{{namespace}}/tables/{{table}}").as_str(),
        AdminOperation(&TABLE_EXISTS_HANDLER),
    )?;
    r.insert(
        Method::GET,
        format!("{prefix}/{{warehouse}}/namespaces/{{namespace}}/tables/{{table}}/credentials").as_str(),
        AdminOperation(&LOAD_CREDENTIALS_HANDLER),
    )?;
    r.insert(
        Method::POST,
        format!("{prefix}/{{warehouse}}/namespaces/{{namespace}}/tables/{{table}}").as_str(),
        AdminOperation(&COMMIT_TABLE_HANDLER),
    )?;
    r.insert(
        Method::DELETE,
        format!("{prefix}/{{warehouse}}/namespaces/{{namespace}}/tables/{{table}}").as_str(),
        AdminOperation(&DROP_TABLE_HANDLER),
    )?;
    r.insert(
        Method::GET,
        format!("{prefix}/{{warehouse}}/namespaces/{{namespace}}/views/{{view}}").as_str(),
        AdminOperation(&LOAD_VIEW_HANDLER),
    )?;
    r.insert(
        Method::HEAD,
        format!("{prefix}/{{warehouse}}/namespaces/{{namespace}}/views/{{view}}").as_str(),
        AdminOperation(&VIEW_EXISTS_HANDLER),
    )?;
    r.insert(
        Method::POST,
        format!("{prefix}/{{warehouse}}/namespaces/{{namespace}}/views/{{view}}").as_str(),
        AdminOperation(&REPLACE_VIEW_HANDLER),
    )?;
    r.insert(
        Method::DELETE,
        format!("{prefix}/{{warehouse}}/namespaces/{{namespace}}/views/{{view}}").as_str(),
        AdminOperation(&DROP_VIEW_HANDLER),
    )?;
    r.insert(
        Method::GET,
        format!("{prefix}/{{warehouse}}/namespaces/{{namespace}}/tables/{{table}}/refs").as_str(),
        AdminOperation(&LIST_TABLE_REFS_HANDLER),
    )?;
    r.insert(
        Method::PUT,
        format!("{prefix}/{{warehouse}}/namespaces/{{namespace}}/tables/{{table}}/refs/{{ref}}").as_str(),
        AdminOperation(&PUT_TABLE_REF_HANDLER),
    )?;
    r.insert(
        Method::DELETE,
        format!("{prefix}/{{warehouse}}/namespaces/{{namespace}}/tables/{{table}}/refs/{{ref}}").as_str(),
        AdminOperation(&DELETE_TABLE_REF_HANDLER),
    )?;
    r.insert(
        Method::GET,
        format!("{prefix}/{{warehouse}}/namespaces/{{namespace}}/tables/{{table}}/metadata-location").as_str(),
        AdminOperation(&GET_TABLE_METADATA_LOCATION_HANDLER),
    )?;
    r.insert(
        Method::PUT,
        format!("{prefix}/{{warehouse}}/namespaces/{{namespace}}/tables/{{table}}/metadata-location").as_str(),
        AdminOperation(&UPDATE_TABLE_METADATA_LOCATION_HANDLER),
    )?;
    r.insert(
        Method::POST,
        format!("{prefix}/{{warehouse}}/namespaces/{{namespace}}/tables/{{table}}/maintenance/metadata").as_str(),
        AdminOperation(&TABLE_METADATA_MAINTENANCE_HANDLER),
    )?;
    r.insert(
        Method::GET,
        format!("{prefix}/{{warehouse}}/namespaces/{{namespace}}/tables/{{table}}/maintenance/config").as_str(),
        AdminOperation(&GET_TABLE_MAINTENANCE_CONFIG_HANDLER),
    )?;
    r.insert(
        Method::PUT,
        format!("{prefix}/{{warehouse}}/namespaces/{{namespace}}/tables/{{table}}/maintenance/config").as_str(),
        AdminOperation(&PUT_TABLE_MAINTENANCE_CONFIG_HANDLER),
    )?;
    r.insert(
        Method::GET,
        format!("{prefix}/{{warehouse}}/namespaces/{{namespace}}/tables/{{table}}/maintenance/jobs/{{job}}").as_str(),
        AdminOperation(&GET_TABLE_MAINTENANCE_JOB_HANDLER),
    )?;
    r.insert(
        Method::GET,
        format!("{prefix}/{{warehouse}}/namespaces/{{namespace}}/tables/{{table}}/maintenance/scheduler").as_str(),
        AdminOperation(&GET_TABLE_MAINTENANCE_SCHEDULER_HANDLER),
    )?;
    r.insert(
        Method::POST,
        format!("{prefix}/{{warehouse}}/namespaces/{{namespace}}/tables/{{table}}/maintenance/scheduler/run").as_str(),
        AdminOperation(&RUN_TABLE_MAINTENANCE_SCHEDULER_HANDLER),
    )?;
    r.insert(
        Method::POST,
        format!("{prefix}/{{warehouse}}/namespaces/{{namespace}}/tables/{{table}}/maintenance/worker/run").as_str(),
        AdminOperation(&RUN_TABLE_MAINTENANCE_WORKER_HANDLER),
    )?;
    r.insert(
        Method::POST,
        format!("{prefix}/{{warehouse}}/namespaces/{{namespace}}/tables/{{table}}/maintenance/jobs/{{job}}/heartbeat").as_str(),
        AdminOperation(&HEARTBEAT_TABLE_MAINTENANCE_JOB_HANDLER),
    )?;
    r.insert(
        Method::POST,
        format!("{prefix}/{{warehouse}}/namespaces/{{namespace}}/tables/{{table}}/maintenance/jobs/{{job}}/quarantine").as_str(),
        AdminOperation(&TABLE_MAINTENANCE_QUARANTINE_HANDLER),
    )?;
    r.insert(
        Method::GET,
        format!("{prefix}/{{warehouse}}/namespaces/{{namespace}}/tables/{{table}}/catalog/export").as_str(),
        AdminOperation(&EXPORT_TABLE_CATALOG_HANDLER),
    )?;
    r.insert(
        Method::POST,
        format!("{prefix}/{{warehouse}}/namespaces/{{namespace}}/tables/{{table}}/catalog/import").as_str(),
        AdminOperation(&IMPORT_TABLE_CATALOG_HANDLER),
    )?;
    r.insert(
        Method::GET,
        format!("{prefix}/{{warehouse}}/namespaces/{{namespace}}/tables/{{table}}/catalog/external").as_str(),
        AdminOperation(&EXTERNAL_CATALOG_BRIDGE_HANDLER),
    )?;
    r.insert(
        Method::PUT,
        format!("{prefix}/{{warehouse}}/namespaces/{{namespace}}/tables/{{table}}/catalog/external").as_str(),
        AdminOperation(&PUT_EXTERNAL_CATALOG_BRIDGE_HANDLER),
    )?;
    r.insert(
        Method::POST,
        format!("{prefix}/{{warehouse}}/namespaces/{{namespace}}/tables/{{table}}/catalog/external/sync").as_str(),
        AdminOperation(&SYNC_EXTERNAL_CATALOG_BRIDGE_HANDLER),
    )?;
    r.insert(
        Method::GET,
        format!("{prefix}/{{warehouse}}/namespaces/{{namespace}}/tables/{{table}}/catalog/diagnostics").as_str(),
        AdminOperation(&GET_TABLE_CATALOG_DIAGNOSTICS_HANDLER),
    )?;
    r.insert(
        Method::POST,
        format!("{prefix}/{{warehouse}}/namespaces/{{namespace}}/tables/{{table}}/catalog/recovery").as_str(),
        AdminOperation(&RECOVER_TABLE_CATALOG_HANDLER),
    )?;
    r.insert(
        Method::POST,
        format!("{prefix}/{{warehouse}}/namespaces/{{namespace}}/tables/{{table}}/catalog/rollback").as_str(),
        AdminOperation(&ROLLBACK_TABLE_CATALOG_HANDLER),
    )?;

    Ok(())
}
