/* dropidx_test.c - verify BOTH DROP INDEX spellings work and do the same thing.
 *
 *     DROP INDEX <name>;                  (ISQL's own form - must still work)
 *     DROP INDEX <name> ON <table>;       (standard SQL - newly accepted)
 *
 * Uses the embedded owner-access pattern, same as the SDK example.
 */
#include <stdio.h>
#include <string.h>
#include "isql.h"

static int pass = 0, fail = 0;

static void check(int ok, const char *what)
{
    if (ok) { printf("  [ok]   %s\n", what); pass++; }
    else    { printf("  [FAIL] %s\n", what); fail++; }
}

int main(int argc, char **argv)
{
    const char *home = (argc > 1) ? argv[1] : "C:\\ISQL";
    KINT64 inst, sid, q;

    inst = ISQL_CreateInternetSqlInstance();
    ISQL_NoNetworkMode(inst);
    ISQL_DisableMessage(inst);
    sid = ISQL_StartInternetSql(inst, (char *)home, "", "");
    if (!sid) { printf("cannot start engine at %s\n", home); return 2; }

    q = ISQL_NewObject(sid);
    ISQL_Exec(q, "use default;");
    ISQL_SetOwnerAccess(q);

    ISQL_Exec(q, "drop table idxtest;");
    check(ISQL_Exec(q, "create table idxtest (id number(5), dept char(10));") != 0,
          "create table");

    /* --- form 1: DROP INDEX <name>;  (must still work, unchanged) --- */
    ISQL_Exec(q, "create index idx_a on idxtest (dept);");
    check(ISQL_Exec(q, "drop index idx_a;") != 0,
          "DROP INDEX <name>;                (ISQL form)");

    /* --- form 2: DROP INDEX <name> ON <table>;  (standard SQL) --- */
    ISQL_Exec(q, "create index idx_b on idxtest (dept);");
    check(ISQL_Exec(q, "drop index idx_b on idxtest;") != 0,
          "DROP INDEX <name> ON <table>;     (standard SQL form)");

    /* DROP is a REVERSIBLE soft-delete: the catalog entry is marked dropped and
       the index file is kept so RECOVER INDEX can restore it. The name therefore
       stays reserved, and re-creating it is EXPECTED to be refused. That is the
       designed behaviour, not a failed drop - use DELETE INDEX to free the name. */
    {
        KINT64 r1 = ISQL_Exec(q, "create index idx_a on idxtest (dept);");
        printf("     recreate idx_a -> ret=%lld status=[%s]\n", (long long)r1, ISQL_Status(q));
        check(r1 == 0, "name stays reserved after DROP form 1 (drop is reversible)");
    }
    {
        KINT64 r2 = ISQL_Exec(q, "create index idx_b on idxtest (dept);");
        printf("     recreate idx_b -> ret=%lld status=[%s]\n", (long long)r2, ISQL_Status(q));
        check(r2 == 0, "name stays reserved after DROP form 2 (drop is reversible)");
    }
    /* control: a brand-new name must create cleanly, proving CREATE INDEX itself
       works here and the two above are specifically about name reuse */
    {
        KINT64 r3 = ISQL_Exec(q, "create index idx_new on idxtest (dept);");
        printf("     create idx_new -> ret=%lld status=[%s]\n", (long long)r3, ISQL_Status(q));
        check(r3 != 0, "control: fresh index name creates cleanly");
    }

    /* DROP is a REVERSIBLE soft-delete (that is why RECOVER INDEX exists), so the
       name stays reserved. Check the two follow-on paths a user actually needs. */
    {
        KINT64 r4 = ISQL_Exec(q, "recover index idx_a;");
        printf("     recover idx_a  -> ret=%lld status=[%s]\n", (long long)r4, ISQL_Status(q));
        check(r4 != 0, "RECOVER INDEX brings back a dropped index");
    }
    {
        KINT64 r5 = ISQL_Exec(q, "delete index idx_b;");
        printf("     delete idx_b   -> ret=%lld status=[%s]\n", (long long)r5, ISQL_Status(q));
        KINT64 r6 = ISQL_Exec(q, "create index idx_b on idxtest (dept);");
        printf("     recreate idx_b -> ret=%lld status=[%s]\n", (long long)r6, ISQL_Status(q));
        check(r6 != 0, "DELETE INDEX frees the name for reuse");
    }

    ISQL_Exec(q, "drop table idxtest;");

    printf("\n============================================\n");
    printf("DROP INDEX test: %d passed, %d failed\n", pass, fail);
    printf("============================================\n");

    /* NOTE: deliberately no ISQL_DeleteInstance - see README compatibility note 6 */
    ISQL_StopInternetSql(sid);
    return fail ? 1 : 0;
}
