//
// initialize.
//
// if first call, attach and startup.
// open server.
//
// return file error.
//
static int do_init(JNIEnv *j_env) {
    int   argc;
    char *argv[1];
    int   ferr;
    int   perr;

    perr = pthread_mutex_lock(&mutex);
    assert(perr == 0);
    if (inited)
        ferr = XZFIL_ERR_OK;
    else {
        do_reg_hash_cb(NULL); // ref to make cmplr happy
        argc = 0;
        argv[0] = NULL;
        inited = true;
        try {
            ferr = msg_init_attach(&argc, (char ***) &argv, 0, NULL);
        } catch (SB_Fatal_Excep &fatal_exc) {
            if (verbose)
                printf("cli: msg_init_attach threw exc=%s, setting PATHDOWN\n",
                       fatal_exc.what());
            ferr = XZFIL_ERR_PATHDOWN;
        } catch (...) {
            if (verbose)
                printf("cli: msg_init_attach threw unknown exc, setting PATHDOWN\n");
            ferr = XZFIL_ERR_PATHDOWN;
        }
        if (ferr == XZFIL_ERR_OK) {
            try {
                ferr = msg_mon_process_startup(false);
            } catch (SB_Fatal_Excep &fatal_exc) {
                if (verbose)
                    printf("cli: msg_mon_process_startup threw exc=%s, setting PATHDOWN\n",
                           fatal_exc.what());
                ferr = XZFIL_ERR_PATHDOWN;
            } catch (...) {
                if (verbose)
                    printf("cli: msg_mon_process_startup threw unknown exc, setting PATHDOWN\n");
                ferr = XZFIL_ERR_PATHDOWN;
            }
        }
    }
    if (ferr == XZFIL_ERR_OK) {
        if (oid < 0) {
            ferr = do_cli_open(j_env, &phandle, &oid);
            if (verbose)
                printf("cli: open-err=%d\n", ferr);
        }
    }
    perr = pthread_mutex_unlock(&mutex);
    assert(perr == 0);

    return ferr;
}
//
// client main
//
int main(int argc, char *argv[]) {
    enum {           TO = 1000 };
    int              ferr;
    long             id;
    int              inx;
    int              oid;
    SB_Phandle_Type  phandle;
    long             t_elapsed;
    struct timeval   t_start;
    struct timeval   t_stop;
    char ascii_buffer[MAX_DATE_TIME_BUFF_LEN + 1];

    do_init(argc, argv);

    do_cli_open(j_env, &phandle, &oid);

    gettimeofday(&t_start, NULL);
    for (inx = 0; inx < loop; inx++) {
        if (idt) {
            do_cli_id(&phandle, TO, &id);
            do_cli_id_to_string(&phandle, TO, id, ascii_buffer);
            do_cli_string_to_id(&phandle, TO, &id, ascii_buffer);
        } else {
            do_cli_ping(&phandle, TO);
            do_cli_id(&phandle, TO, &id);
            do_cli_id_to_string(&phandle, TO, id, ascii_buffer);
            do_cli_string_to_id(&phandle, TO, &id, ascii_buffer);
        }
    }
    gettimeofday(&t_stop, NULL);
    t_elapsed = (t_stop.tv_sec * 1000000 + t_stop.tv_usec) -
                (t_start.tv_sec * 1000000 + t_start.tv_usec);
    printf("elapsed time (gettimeofday us)=%ld, ops/sec=%f\n",
           t_elapsed, (double) loop / ((double) t_elapsed / 1000000));

    ferr = msg_mon_close_process(&phandle);
    assert(ferr == XZFIL_ERR_OK);
    ferr = msg_mon_process_shutdown();
    assert(ferr == XZFIL_ERR_OK);
    return 0;
}
//
// initialize.
//
// if first call, attach and startup.
// open server.
//
// return file error.
//
static int do_init(JNIEnv *pp_j_env) {
    char *la_argv[1];
    int   lv_argc;
    int   lv_ferr;
    int   lv_perr;

    if (gv_verbose)
       printf("cli: do_init start\n");
    lv_perr = pthread_mutex_lock(&gv_mutex);
    assert(lv_perr == 0);
    if (gv_inited)
        lv_ferr = XZFIL_ERR_OK;
    else {
        do_reg_hash_cb(NULL); // ref to make cmplr happy
        lv_argc = 0;
        la_argv[0] = NULL;
        gv_inited = true;
        try {
            lv_ferr = msg_init_attach(&lv_argc, (char ***) &la_argv, 0, NULL);
            if (gv_verbose)
                printf("cli: msg_init_attach ferr=%d\n", lv_ferr);
        } catch (SB_Fatal_Excep &fatal_exc) {
            if (gv_verbose)
                printf("cli: msg_init_attach threw exc=%s, setting PATHDOWN\n",
                       fatal_exc.what());
            lv_ferr = XZFIL_ERR_PATHDOWN;
        } catch (...) {
            if (gv_verbose)
                printf("cli: msg_init_attach threw unknown exc, setting PATHDOWN\n");
            lv_ferr = XZFIL_ERR_PATHDOWN;
        }
        if (lv_ferr == XZFIL_ERR_OK) {
            try {
                lv_ferr = msg_mon_process_startup4(false, true, true);
            } catch (SB_Fatal_Excep &fatal_exc) {
                if (gv_verbose)
                    printf("cli: msg_mon_process_startup threw exc=%s, setting PATHDOWN\n",
                           fatal_exc.what());
                lv_ferr = XZFIL_ERR_PATHDOWN;
            } catch (...) {
                if (gv_verbose)
                    printf("cli: msg_mon_process_startup threw unknown exc, setting PATHDOWN\n");
                lv_ferr = XZFIL_ERR_PATHDOWN;
            }
        } else if (lv_ferr == XZFIL_ERR_INVALIDSTATE) {
            // attach failed, already initialized, clear error
            lv_ferr = XZFIL_ERR_OK;
        }
    }
    if (lv_ferr == XZFIL_ERR_OK) {
        if (gv_oid < 0) {
            lv_ferr = do_cli_open(pp_j_env, &gv_phandle, &gv_oid);
            if (gv_verbose)
                printf("cli: open-err=%d\n", lv_ferr);
        }
    }
    lv_perr = pthread_mutex_unlock(&gv_mutex);
    assert(lv_perr == 0);

    if (gv_verbose)
       printf("cli: do_init end ferr=%d\n", lv_ferr);

    return lv_ferr;
}