int samtools_test_trans_tbl_init_main(int argc, char**argv)
{
    const int NUM_TESTS = 6;
    int verbose = 0;
    int success = 0;
    int failure = 0;
    int getopt_char;
    while ((getopt_char = getopt(argc, argv, "v")) != -1) {
        switch (getopt_char) {
            case 'v':
                ++verbose;
                break;
            default:
                break;
        }
    }

    // Set the seed to a fixed value so that calls to lrand48 within functions return predictable values
    const long GIMMICK_SEED = 0x1234330e;
    srand48(GIMMICK_SEED);

    bam_hdr_t* out;
    bam_hdr_t* translate;

    if (verbose) fprintf(pysam_stdout, "BEGIN test 1\n");
    // setup
    trans_tbl_t tbl_1;
    merged_header_t *merged_hdr = init_merged_header();
    translate = setup_test_1(merged_hdr);
    assert(translate);
    // test
    if (verbose > 1) {
        fprintf(pysam_stdout, "translate\n");
        dump_header(translate);
    }
    if (verbose) fprintf(pysam_stdout, "RUN test 1\n");
    trans_tbl_init(merged_hdr, translate, &tbl_1, false, false, true, NULL);
    out = finish_merged_header(merged_hdr);
    free_merged_header(merged_hdr);
    if (verbose) fprintf(pysam_stdout, "END RUN test 1\n");
    if (verbose > 1) {
        fprintf(pysam_stdout, "translate\n");
        dump_header(translate);
        fprintf(pysam_stdout, "out\n");
        dump_header(out);
    }
    if (check_test_1(translate, out, &tbl_1)) {
        if (verbose) fprintf(pysam_stdout, "Test 1 : PASS\n");
        ++success;
    } else {
        if (verbose) fprintf(pysam_stdout, "Test 1 : FAIL\n");
        fprintf(pysam_stderr, "Test 1 : FAIL\n");
        ++failure;
    }
    // teardown
    bam_hdr_destroy(translate);
    bam_hdr_destroy(out);
    trans_tbl_destroy(&tbl_1);
    if (verbose) fprintf(pysam_stdout, "END test 1\n");

    // test
    if (verbose) fprintf(pysam_stdout, "BEGIN test 2\n");
    // reinit
    trans_tbl_t tbl_2;

    merged_hdr = init_merged_header();
    translate = setup_test_2(merged_hdr);
    assert(translate);
    if (verbose > 1) {
        fprintf(pysam_stdout, "translate\n");
        dump_header(translate);
    }
    if (verbose) fprintf(pysam_stdout, "RUN test 2\n");
    trans_tbl_init(merged_hdr, translate, &tbl_2, false, false, true, NULL);
    out = finish_merged_header(merged_hdr);
    free_merged_header(merged_hdr);
    if (verbose) fprintf(pysam_stdout, "END RUN test 2\n");
    if (verbose > 1) {
        fprintf(pysam_stdout, "translate\n");
        dump_header(translate);
        fprintf(pysam_stdout, "out\n");
        dump_header(out);
    }
    if (check_test_2(translate, out, &tbl_2)) {
        if (verbose) fprintf(pysam_stdout, "Test 2 : PASS\n");
        ++success;
    } else {
        if (verbose) fprintf(pysam_stdout, "Test 2 : FAIL\n");
        fprintf(pysam_stderr, "Test 2 : FAIL\n");
        ++failure;
    }
    // teardown
    bam_hdr_destroy(translate);
    bam_hdr_destroy(out);
    trans_tbl_destroy(&tbl_2);
    if (verbose) fprintf(pysam_stdout, "END test 2\n");

    // test
    if (verbose) fprintf(pysam_stdout, "BEGIN test 3\n");
    // reinit
    trans_tbl_t tbl_3;
    merged_hdr = init_merged_header();
    translate = setup_test_3(merged_hdr);
    assert(translate);
    if (verbose > 1) {
        fprintf(pysam_stdout, "translate\n");
        dump_header(translate);
     }
    if (verbose) fprintf(pysam_stdout, "RUN test 3\n");
    trans_tbl_init(merged_hdr, translate, &tbl_3, false, false, true, NULL);
    out = finish_merged_header(merged_hdr);
    free_merged_header(merged_hdr);
    if (verbose) fprintf(pysam_stdout, "END RUN test 3\n");
    if (verbose > 1) {
        fprintf(pysam_stdout, "translate\n");
        dump_header(translate);
        fprintf(pysam_stdout, "out\n");
        dump_header(out);
    }
    if (check_test_3(translate, out, &tbl_3)) {
        if (verbose) fprintf(pysam_stdout, "Test 3 : PASS\n");
        ++success;
    } else {
        if (verbose) fprintf(pysam_stdout, "Test 3 : FAIL\n");
        fprintf(pysam_stderr, "Test 3 : FAIL\n");
        ++failure;
    }
    // teardown
    bam_hdr_destroy(translate);
    bam_hdr_destroy(out);
    trans_tbl_destroy(&tbl_3);
    if (verbose) fprintf(pysam_stdout, "END test 3\n");

    // test
    if (verbose) fprintf(pysam_stdout, "BEGIN test 4\n");
    // reinit
    trans_tbl_t tbl_4;
    merged_hdr = init_merged_header();
    translate = setup_test_4(merged_hdr);
    assert(translate);
    if (verbose > 1) {
        fprintf(pysam_stdout, "translate\n");
        dump_header(translate);
    }
    if (verbose) fprintf(pysam_stdout, "RUN test 4\n");
    trans_tbl_init(merged_hdr, translate, &tbl_4, false, false, true, NULL);
    out = finish_merged_header(merged_hdr);
    free_merged_header(merged_hdr);
    if (verbose) fprintf(pysam_stdout, "END RUN test 4\n");
    if (verbose > 1) {
        fprintf(pysam_stdout, "translate\n");
        dump_header(translate);
        fprintf(pysam_stdout, "out\n");
        dump_header(out);
    }
    if (check_test_4(translate, out, &tbl_4)) {
        if (verbose) fprintf(pysam_stdout, "Test 4 : PASS\n");
        ++success;
    } else {
        if (verbose) fprintf(pysam_stdout, "Test 4 : FAIL\n");
        fprintf(pysam_stderr, "Test 4 : FAIL\n");
        ++failure;
    }
    // teardown
    bam_hdr_destroy(translate);
    bam_hdr_destroy(out);
    trans_tbl_destroy(&tbl_4);
    if (verbose) fprintf(pysam_stdout, "END test 4\n");

    // test
    if (verbose) fprintf(pysam_stdout, "BEGIN test 5\n");
    // reinit
    trans_tbl_t tbl_5;
    merged_hdr = init_merged_header();
    translate = setup_test_5(merged_hdr);
    assert(translate);
    if (verbose > 1) {

        fprintf(pysam_stdout, "translate\n");
        dump_header(translate);
    }
    if (verbose) fprintf(pysam_stdout, "RUN test 5\n");
    trans_tbl_init(merged_hdr, translate, &tbl_5, false, false, true, NULL);
    out = finish_merged_header(merged_hdr);
    free_merged_header(merged_hdr);
    if (verbose) fprintf(pysam_stdout, "END RUN test 5\n");
    if (verbose > 1) {
        fprintf(pysam_stdout, "translate\n");
        dump_header(translate);
        fprintf(pysam_stdout, "out\n");
        dump_header(out);
    }
    if (check_test_5(translate, out, &tbl_5)) {
        if (verbose) fprintf(pysam_stdout, "Test 5 : PASS\n");
        ++success;
    } else {
        if (verbose) fprintf(pysam_stdout, "Test 5 : FAIL\n");
        fprintf(pysam_stderr, "Test 5 : FAIL\n");
        ++failure;
    }
    // teardown
    bam_hdr_destroy(translate);
    bam_hdr_destroy(out);
    trans_tbl_destroy(&tbl_5);
    if (verbose) fprintf(pysam_stdout, "END test 5\n");

    // test
    if (verbose) fprintf(pysam_stdout, "BEGIN test 6\n");
    // reinit
    trans_tbl_t tbl_6;
    merged_hdr = init_merged_header();
    translate = setup_test_6(merged_hdr);
    assert(translate);
    if (verbose > 1) {
        fprintf(pysam_stdout, "translate\n");
        dump_header(translate);
    }
    if (verbose) fprintf(pysam_stdout, "RUN test 6\n");
    trans_tbl_init(merged_hdr, translate, &tbl_6, false, false, true, "filename");
    out = finish_merged_header(merged_hdr);
    free_merged_header(merged_hdr);
    if (verbose) fprintf(pysam_stdout, "END RUN test 6\n");
    if (verbose > 1) {
        fprintf(pysam_stdout, "translate\n");
        dump_header(translate);
        fprintf(pysam_stdout, "out\n");
        dump_header(out);
    }
    if (check_test_6(translate, out, &tbl_6)) {
        if (verbose) fprintf(pysam_stdout, "Test 6 : PASS\n");
        ++success;
    } else {
        if (verbose) fprintf(pysam_stdout, "Test 6 : FAIL\n");
        fprintf(pysam_stderr, "Test 6 : FAIL\n");
        ++failure;
    }
    // teardown
    bam_hdr_destroy(translate);
    bam_hdr_destroy(out);
    trans_tbl_destroy(&tbl_6);
    if (verbose) fprintf(pysam_stdout, "END test 6\n");

    if (success == NUM_TESTS) {
        return 0;
    } else {
        fprintf(pysam_stderr, "%d failures %d successes\n", failure, success);
        return 1;
    }
}
int main(int argc, char**argv)
{
    // test state
    const int NUM_TESTS = 6;
    int verbose = 0;
    int success = 0;
    int failure = 0;

    int getopt_char;
    while ((getopt_char = getopt(argc, argv, "v")) != -1) {
        switch (getopt_char) {
            case 'v':
                ++verbose;
                break;
            default:
                break;
        }
    }

    bam1_t* b;

    // Setup pysamerr redirect
    size_t len = 0;
    char* res = NULL;
    FILE* orig_pysamerr = fdopen(dup(STDERR_FILENO), "a"); // Save pysamerr
    char* tempfname = (optind < argc)? argv[optind] : "test_bam_translate.tmp";
    FILE* check = NULL;

    // setup
    if (verbose) printf("BEGIN test 1\n");  // TID test
    trans_tbl_t tbl1;
    setup_test_1(&b,&tbl1);
    if (verbose > 1) {
        printf("b\n");
        dump_read(b);
    }
    if (verbose) printf("RUN test 1\n");

    // test
    xfreopen(tempfname, "w", pysamerr); // Redirect pysamerr to pipe
    bam_translate(b, &tbl1);
    fclose(pysamerr);

    if (verbose) printf("END RUN test 1\n");
    if (verbose > 1) {
        printf("b\n");
        dump_read(b);
    }

    // check result
    check = fopen(tempfname, "r");
    if ( (getline(&res, &len, check) == -1 ) &&
        (feof(check) || (res && !strcmp("",res))) ) {
        ++success;
    } else {
        ++failure;
        if (verbose) printf("FAIL test 1\n");
    }
    fclose(check);

    // teardown
    bam_destroy1(b);
    trans_tbl_destroy(&tbl1);
    if (verbose) printf("END test 1\n");

    // setup
    if (verbose) printf("BEGIN test 2\n");  // RG exists and translate test
    trans_tbl_t tbl2;
    setup_test_2(&b,&tbl2);
    if (verbose > 1) {
        printf("b\n");
        dump_read(b);
    }
    if (verbose) printf("RUN test 2\n");

    // test
    xfreopen(tempfname, "w", pysamerr); // Redirect pysamerr to pipe
    bam_translate(b, &tbl2);
    fclose(pysamerr);

    if (verbose) printf("END RUN test 2\n");
    if (verbose > 1) {
        printf("b\n");
        dump_read(b);
    }

    // check result
    check = fopen(tempfname, "r");
    if ( (getline(&res, &len, check) == -1 ) &&
        (feof(check) || (res && !strcmp("",res))) ) {
        ++success;
    } else {
        ++failure;
        if (verbose) printf("FAIL test 2\n");
    }
    fclose(check);

    // teardown
    bam_destroy1(b);
    trans_tbl_destroy(&tbl2);
    if (verbose) printf("END test 2\n");

    if (verbose) printf("BEGIN test 3\n");  // PG exists and translate  test
    // setup
    trans_tbl_t tbl3;
    setup_test_3(&b,&tbl3);
    if (verbose > 1) {
        printf("b\n");
        dump_read(b);
    }
    if (verbose) printf("RUN test 3\n");

    // test
    xfreopen(tempfname, "w", pysamerr); // Redirect pysamerr to pipe
    bam_translate(b, &tbl3);
    fclose(pysamerr);

    if (verbose) printf("END RUN test 3\n");
    if (verbose > 1) {
        printf("b\n");
        dump_read(b);
    }

    // check result
    check = fopen(tempfname, "r");
    if ( (getline(&res, &len, check) == -1 ) &&
        (feof(check) || (res && !strcmp("",res)))) {
        ++success;
    } else {
        ++failure;
        if (verbose) printf("FAIL test 3\n");
    }
    fclose(check);

    // teardown
    bam_destroy1(b);
    trans_tbl_destroy(&tbl3);
    if (verbose) printf("END test 3\n");

    if (verbose) printf("BEGIN test 4\n");  // RG test non-existent
    // setup
    trans_tbl_t tbl4;
    setup_test_4(&b,&tbl4);
    if (verbose > 1) {
        printf("b\n");
        dump_read(b);
    }
    if (verbose) printf("RUN test 4\n");

    // test
    xfreopen(tempfname, "w", pysamerr); // Redirect pysamerr to pipe
    bam_translate(b, &tbl4);
    fclose(pysamerr);

    if (verbose) printf("END RUN test 4\n");
    if (verbose > 1) {
        printf("b\n");
        dump_read(b);
    }
    // check result
    check = fopen(tempfname, "r");
    if ( (getline(&res, &len, check) != -1 ) &&
        res && !strcmp("[bam_translate] RG tag \"rg4hello\" on read \"123456789\" encountered with no corresponding entry in header, tag lost\n",res)) {
        ++success;
    } else {
        ++failure;
        if (verbose) printf("FAIL test 4\n");
    }
    fclose(check);

    // teardown
    bam_destroy1(b);
    trans_tbl_destroy(&tbl4);
    if (verbose) printf("END test 4\n");

    if (verbose) printf("BEGIN test 5\n");  // PG test non-existent
    // setup
    trans_tbl_t tbl5;
    setup_test_5(&b,&tbl5);
    if (verbose > 1) {
        printf("b\n");
        dump_read(b);
        printf("RUN test 5\n");
    }
    // test
    xfreopen(tempfname, "w", pysamerr); // Redirect pysamerr to pipe
    bam_translate(b, &tbl5);
    fclose(pysamerr);

    if (verbose) printf("END RUN test 5\n");
    if (verbose > 1) {
        printf("b\n");
        dump_read(b);
    }

    // check result
    check = fopen(tempfname, "r");
    if ( (getline(&res, &len, check) != -1 ) &&
        res && !strcmp("[bam_translate] PG tag \"pg5hello\" on read \"123456789\" encountered with no corresponding entry in header, tag lost\n",res)) {
        ++success;
    } else {
        ++failure;
        if (verbose) printf("FAIL test 5\n");
    }
    fclose(check);

    // teardown
    bam_destroy1(b);
    trans_tbl_destroy(&tbl5);
    if (verbose) printf("END test 5\n");

    if (verbose) printf("BEGIN test 6\n");  // RG and PG exists and translate test
    // setup
    trans_tbl_t tbl6;
    setup_test_6(&b,&tbl6);
    if (verbose > 1) {
        printf("b\n");
        dump_read(b);
    }
    if (verbose) printf("RUN test 6\n");

    // test
    xfreopen(tempfname, "w", pysamerr); // Redirect pysamerr to pipe
    bam_translate(b, &tbl6);
    fclose(pysamerr);

    if (verbose) printf("END RUN test 6\n");
    if (verbose > 1) {
        printf("b\n");
        dump_read(b);
    }

    // check result
    check = fopen(tempfname, "r");
    if ( (getline(&res, &len, check) == -1 ) &&
        (feof(check) || (res && !strcmp("",res))) ) {
        ++success;
    } else {
        ++failure;
        if (verbose) printf("FAIL test 6\n");
    }
    fclose(check);

    // teardown
    bam_destroy1(b);
    trans_tbl_destroy(&tbl6);
    if (verbose) printf("END test 6\n");

    // Cleanup
    free(res);
    remove(tempfname);
    if (failure > 0)
        fprintf(orig_pysamerr, "%d failures %d successes\n", failure, success);
    fclose(orig_pysamerr);

    return (success == NUM_TESTS)? EXIT_SUCCESS : EXIT_FAILURE;
}