# -*- coding: utf-8 -*-
import datetime

import pytest

from trailblazer.mip import sacct


@pytest.mark.parametrize(
    "time_str, expected_seconds",
    [
        ("02:53:08", (2 * 60 * 60) + (53 * 60)),
        ("3-07:13:56", (3 * 24 * 60 * 60) + (7 * 60 * 60) + (13 * 60)),
        ("18:47.020", (18 * 60)),
        ("00:00:35", 0),
    ],
)
def test_time_to_sec(time_str, expected_seconds):
    # GIVEN a time string
    # WHEN parsing it into number of seconds
    seconds = sacct.time_to_sec(time_str)
    # THEN it should match expected number of seconds (skipping individual secs)
    assert seconds == expected_seconds


@pytest.mark.parametrize(
    "row, expected_job",
    [
        (
            [
                "813887",
                "gatk_genotypegvcfs_case_BOTH",
                "prod001",
                "core",
                "16",
                "10:03.096",
                "00:02:01",
                "2017-06-19T00:44:46",
                "2017-06-19T00:46:47",
                "COMPLETED",
                "0:0",
            ],
            dict(step="gatk_genotypegvcfs", context="case", is_completed=True),
        ),
        (
            [
                "815038",
                "fastqc_ACC2698A3",
                "prod001",
                "core",
                "8",
                "00:00:00",
                "00:37:24",
                "2017-06-20T12:57:45",
                "Unknown",
                "RUNNING",
                "0:0",
            ],
            dict(step="fastqc", context="ACC2698A3", is_completed=False),
        ),
    ],
)
def test_convert_job(row, expected_job):
    # GIVEN a sacct row
    # WHEN parsing it for extracted data
    job = sacct.convert_job(row)
    # THEN it should have an integer for a job id
    assert isinstance(job["id"], int)
    # ... the step should be the job type
    assert job["step"] == expected_job["step"]
    # ... the context should be the family/sample id
    assert job["context"] == expected_job["context"]
    # ... it should be marked as completed only if that is the state
    assert job["is_completed"] == expected_job["is_completed"]
    # ... the "start" should be a date
    assert isinstance(job["start"], datetime.datetime)
    # ... the "end" should be a date unless the job is "running"
    if job["state"] == "RUNNING":
        assert job["end"] is None
    else:
        assert isinstance(job["end"], datetime.datetime)


def test_parse_sacct(files_raw):
    # GIVEN a sacct file with a number of row (1 header, rest jobs)
    lines = len(files_raw["sacct"])
    # WHEN parsing the sacct file
    jobs = sacct.parse_sacct(files_raw["sacct"])
    # THEN it should find all relevant rows
    assert len(jobs) == (lines - 1)


def test_filter_jobs(failed_sacct_jobs):
    # GIVEN a sacct output with COMPLETED, FAILED, and CANCELLED jobs
    completed_count = 17
    failed_count = 2
    cancelled_count = 34
    # WHEN filtering on "failed" jobs
    failed_jobs = sacct.filter_jobs(failed_sacct_jobs, failed=True)
    # THEN it should return jobs which are "failed" or "cancelled"
    assert len(failed_jobs) == (failed_count + cancelled_count)

    # WHEN filtering on "OK" jobs
    ok_jobs = sacct.filter_jobs(failed_sacct_jobs, failed=False)
    # THEN it should return jobs which are "completed"
    assert len(ok_jobs) == completed_count
