example_bam <- system.file("tests",
    "test2.bam",
    package = "megadepth",
    mustWork = TRUE
)

example_jxs <- bam_to_junctions(example_bam,
    all_junctions = TRUE,
    junctions = TRUE,
    overwrite = TRUE
)

all_jxs <- read_junction_table(example_jxs[["all_jxs.tsv"]])

##### read_junction_table #####

test_that("read_junction_table has correct output", {
    expect_equal(
        all_jxs,
        read_junction_table(
            "https://raw.githubusercontent.com/ChristopherWilks/megadepth/master/tests/test2.bam.all_jxs.tsv"
        )
    )

    suppressWarnings(expr = {
        jxs <- read_junction_table(example_jxs[["jxs.tsv"]])
        chris_jxs <- read_junction_table(
            "https://raw.githubusercontent.com/ChristopherWilks/megadepth/master/tests/test2.bam.jxs.tsv"
        )
    })

    expect_equal(jxs, chris_jxs, ignore_attr = TRUE)
})

test_that("read_junction_table catches user input errors", {
    expect_error(
        read_junction_table(tsv_file = "no_correct_extension"),
        'tsv_file must have the extension "all_jxs.tsv" or "jxs.tsv"'
    )
})

##### process_junction_table ######

# Don't test on windows as needs to download and run .sh script
if (!xfun::is_windows()) {
    # download Chris' script for testing
    process_jx_script_path <- file.path(tempdir(), "process_jx_output.sh")

    download.file(
        "https://raw.githubusercontent.com/ChristopherWilks/megadepth/master/junctions/process_jx_output.sh",
        process_jx_script_path
    )

    Sys.chmod(process_jx_script_path, "0755")

    # wrap using process_jx_output.sh in function
    process_jx_output_shell <- function(all_jxs_path, process_jx_script_path) {
        system(paste(
            process_jx_script_path,
            all_jxs_path
        ))

        # processed junctions
        processed_jxs <- readr::read_delim(
            paste0(all_jxs_path, ".sjout"),
            delim = "\t",
            col_names = c(
                "chr",
                "start",
                "end",
                "strand",
                "intron_motif",
                "annotated",
                "uniquely_mapping_reads",
                "multimapping_reads",
                "X9"
            )
        ) %>% dplyr::select(-X9)

        return(processed_jxs)
    }

    test_that("process_junction_table has correct output", {
        # also read/test junctions from test.bam (as well as test2.bam above)
        example_bam2 <- system.file("tests",
            "test.bam",
            package = "megadepth",
            mustWork = TRUE
        )

        example_jxs2 <- bam_to_junctions(example_bam2,
            all_junctions = TRUE,
            junctions = TRUE,
            overwrite = TRUE
        )

        suppressWarnings(expr = {
            processed_jxs2_shell <- process_jx_output_shell(
                all_jxs_path = example_jxs2[["all_jxs.tsv"]],
                process_jx_script_path
            )
        })

        suppressWarnings(expr = {
            processed_jxs_shell <- process_jx_output_shell(
                all_jxs_path = example_jxs[["all_jxs.tsv"]],
                process_jx_script_path
            )
        })

        # ignore_attr = TRUE is needed as there are "spec" and "problems"
        # attributes that are created on the tibble through read_delim()
        expect_equal(process_junction_table(all_jxs),
            processed_jxs_shell,
            ignore_attr = TRUE
        )

        expect_equal(
            example_jxs2[["all_jxs.tsv"]] %>%
                read_junction_table() %>%
                process_junction_table(),
            processed_jxs2_shell,
            ignore_attr = TRUE
        )
    })
}

test_that("process_junction_table catches user input errors", {
    suppressWarnings(expr = {
        jxs <- read_junction_table(example_jxs[["jxs.tsv"]])
    })

    expect_error(
        process_junction_table(jxs),
        "all_jxs argument should have colnames"
    )
})

# use local full-size bam for testing
# avoid testing when local bam is not available, to avoid large test times
# in which case, unit testing relies on using test.bam/test2.bam above
bam_path <- "/data/RNA_seq_diag/niccolo_X_linked_dystonia/180420-140039/STAR/NIAA_Aligned.sortedBysamtools.out.bam"

if (file.exists(bam_path)) {
    local_bam_jxs <- bam_to_junctions(bam_path,
        all_junctions = TRUE,
        overwrite = TRUE
    )

    # take first n_rows_to_test rows
    n_rows_to_test <- 1000000
    local_bam_jxs_head <- local_bam_jxs[["all_jxs.tsv"]] %>%
        gsub(".all_jxs", "_head.all_jxs", .)

    local_bam_jxs[["all_jxs.tsv"]] %>%
        readr::read_delim(
            n_max = n_rows_to_test,
            col_names = FALSE,
            delim = "\t"
        ) %>%
        readr::write_delim(local_bam_jxs_head,
            col_names = FALSE,
            delim = "\t"
        )

    local_bam_jxs_processed <- read_junction_table(local_bam_jxs_head) %>%
        process_junction_table()

    suppressWarnings(
        local_bam_jxs_processed_shell <-
            process_jx_output_shell(
                local_bam_jxs_head,
                process_jx_script_path
            )
    )

    test_that("process_junction_table works on a larger set of jxs", {
        expect_equal(local_bam_jxs_processed,
            local_bam_jxs_processed_shell,
            ignore_attr = TRUE
        )
    })
}
