/*-------------------------------------------------------------------------
 * Copyright (c) Microsoft Corporation.  All rights reserved.
 *
 * documentdb_tests/src/commands/unsupported_commands.rs
 *
 *-------------------------------------------------------------------------
 */

use bson::doc;
use mongodb::Database;

use crate::utils::commands;

const UNSUPPORTED_COMMANDS: &[&str] = &[
    "_cloneCatalogData",
    "_cloneCollectionOptionsFromPrimaryShard",
    "_configsvrAddShard",
    "_configsvrAddShardToZone",
    "_configsvrBalancerStart",
    "_configsvrBalancerStatus",
    "_configsvrBalancerStop",
    "_configsvrCommitChunkMerge",
    "_configsvrCommitChunkMigration",
    "_configsvrCommitChunkSplit",
    "_configsvrCommitMovePrimary",
    "_configsvrCreateCollection",
    "_configsvrCreateDatabase",
    "_configsvrDropCollection",
    "_configsvrDropDatabase",
    "_configsvrEnableSharding",
    "_configsvrMoveChunk",
    "_configsvrMovePrimary",
    "_configsvrRemoveShard",
    "_configsvrRemoveShardFromZone",
    "_configsvrShardCollection",
    "_configsvrUpdateZoneKeyRange",
    "_flushDatabaseCacheUpdates",
    "_flushRoutingTableCacheUpdates",
    "_getNextSessionMods",
    "_getUserCacheGeneration",
    "_isSelf",
    "_mergeAuthzCollections",
    "_migrateClone",
    "_movePrimary",
    "_recvChunkAbort",
    "_recvChunkCommit",
    "_recvChunkStart",
    "_recvChunkStatus",
    "_shardsvrShardCollection",
    "_transferMods",
    "appendOplogNote",
    "applyOps",
    "authenticate",
    "authSchemaUpgrade",
    "availableQueryOptions",
    "checkShardingIndex",
    "cleanupOrphaned",
    "clone",
    "cloneCollection",
    "cloneCollectionAsCapped",
    "connPoolStats",
    "connPoolSync",
    "convertToCapped",
    "copydb",
    "copydbgetnonce",
    "copydbsaslstart",
    "createUniqueOrCompoundIndexOnNestedPath",
    "currentOpCtx",
    "customAction",
    "dataSize",
    "dbHash",
    "deleteIndexes",
    "diagLogging",
    "driverOIDTest",
    "dropAllRolesFromDatabase",
    "dropAllUsersFromDatabase",
    "enableSharding",
    "eval",
    "features",
    "filemd5",
    "forceerror",
    "fsync",
    "fsyncUnlock",
    "geoNear",
    "geoSearch",
    "getDatabaseVersion",
    "getDiagnosticData",
    "getFreeMonitoringStatus",
    "getLastError",
    "getLastRequestStatistics",
    "getNonce",
    "getPrevError",
    "getShardVersion",
    "grantPrivilegesToRole",
    "grantRolesToRole",
    "grantRolesToUser",
    "group",
    "handshake",
    "invalidateUserCache",
    "lockInfo",
    "logRotate",
    "mapReduce",
    "mapreduce.shardedfinish",
    "mergeChunks",
    "moveChunk",
    "parallelCollectionScan",
    "planCacheListPlans",
    "planCacheListQueryShapes",
    "profile",
    "refreshSessionsInternal",
    "repairCursor",
    "repairDatabase",
    "replSetAbortPrimaryCatchUp",
    "replSetDeclareElectionWinner",
    "replSetElect",
    "replSetFreeze",
    "replSetFresh",
    "replSetGetConfig",
    "replSetGetRBID",
    "replSetGetStatus",
    "replSetHeartbeat",
    "replSetInitiate",
    "replSetMaintenance",
    "replSetReconfig",
    "replSetRequestVotes",
    "replSetResizeOplog",
    "replSetStepDown",
    "replSetStepUp",
    "replSetSyncFrom",
    "replSetUpdatePosition",
    "resetError",
    "reSync",
    "revokePrivilegesFromRole",
    "revokeRolesFromRole",
    "revokeRolesFromUser",
    "serverStatus",
    "setFeatureCompatibilityVersion",
    "setFreeMonitoring",
    "setParameter",
    "setShardVersion",
    "shardConnPoolStats",
    "shardingState",
    "shutdown",
    "splitChunk",
    "splitVector",
    "startSession",
    "top",
    "touch",
    "unsetSharding",
    "writebacklisten",
];

pub async fn validate_command_not_found(db: &Database) -> () {
    commands::execute_command_and_validate_error(
        db,
        doc! { "atlasVersion": 1 },
        59,
        "Command 'atlasVersion' not found.",
        "CommandNotFound",
    )
    .await;
}

pub async fn validate_commands_not_supported(db: &Database) -> () {
    for command_name in UNSUPPORTED_COMMANDS {
        let expected_msg = format!("Command '{command_name}' not supported.");
        commands::execute_command_and_validate_error(
            db,
            doc! { *command_name: 1 },
            115,
            &expected_msg,
            "CommandNotSupported",
        )
        .await;
    }
}
