#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
Tests module for the roc.punk plugin.
"""

import pytest
from argparse import Namespace
from datetime import datetime, timedelta

from poppy.core.pipeline import Pipeline
from poppy.core.test import CommandTestCase, TaskTestCase

from roc.punk.tasks import SBMReport, SBMQuery
from roc.punk.tests.test_punk import PunkTest
from roc.dingo.models.data import SbmLog


def getSbmData():
    today = datetime.now()

    # Define all possible sbm objects
    nb_days = [5, 10, 10]
    sbm_types = [1, 1, 2]

    dates = [
        today
        - timedelta(
            days=n, hours=today.hour, minutes=today.minute, seconds=today.second
        )
        for n in nb_days
    ]

    sbms = [
        SbmLog(
            id=i,
            sbm_type=sbm_types[i],
            cuc_time=f"694407463:30{i}88",
            obt_time=dates[i],
            utc_time=dates[i],
            sbm_qf=2153,
            sbm_algo=1,
            status="Unknown",
        )
        for i, n in enumerate(nb_days)
    ]

    return sbms


def getFilteredSbmData(sbms, type, days):
    today = datetime.now()

    # Define the date to consider
    date_max = today - timedelta(
        days=days, hours=today.hour, minutes=today.minute, seconds=today.second
    )

    filtered_sbms = [
        sbm for sbm in sbms if sbm.utc_time >= date_max and sbm.sbm_type == type
    ]

    return filtered_sbms


def storeSbmData(sbms, session):
    for sbm in sbms:
        session.add(sbm)
    session.flush()


# REMEMBER TO TEST TASKS BEFORE COMMANDS


class TestSBMQuery(TaskTestCase):
    """
    With data generated by getSbmData(), report should notify
        `nb_results` events of `sbm_type`  for the latest `days`

    """

    @pytest.mark.parametrize(
        "sbm_type, days, nb_results",
        [
            (1, 8, 1),
            (1, 15, 2),
            (2, 8, 0),
            (2, 15, 1),
        ],
    )
    def test_sbm_query(self, sbm_type, days, nb_results):
        # --- set up arguments ---
        args = Namespace(type=sbm_type, days=days, dry_run=False)

        # --- database setup ---
        session = PunkTest.setup_session()

        # empty the table FileLog
        session.query(SbmLog).delete()
        session.flush()

        # --- ensure database is empty ---
        db_before = session.query(SbmLog).all()
        assert len(db_before) == 0

        # --- initialise db ---
        sbms = getSbmData()
        for sbm in sbms:
            session.add(sbm)
        session.flush()

        db_after = session.query(SbmLog).all()
        assert len(db_after) == len(sbms)

        # --- initialise task & pipeline --
        self.task = SBMQuery()
        self.task.pipeline = Pipeline(args)
        self.task.instantiate_targets()
        self.task.session = session

        # --- run the task ---
        self.run_task()

        # --- get results ---
        report_params = self.task.outputs["report_params"].data

        # --- make assertions ---
        if nb_results == 0:
            assert report_params is None
        else:
            assert "title" in report_params
            assert "labels" in report_params
            assert "assignee_id" in report_params
            assert "description" in report_params

            search_desc = f"{nb_results} SBM type {sbm_type} "
            assert search_desc in report_params["description"]

        session.close()


class TestSBMReport(TaskTestCase):
    def test_sbm_report(self):
        # --- set up arguments ---
        args = Namespace(token="xxx", dry_run=False)

        params = {}
        params["title"] = "Issue title"
        params["labels"] = "SBM"
        params["assignee_id"] = 142
        params["description"] = "Issue description"

        # --- initialise task & pipeline --
        self.task = SBMReport()
        self.task.pipeline = Pipeline(args)
        self.task.instantiate_targets()
        self.task.inputs["report_params"].data = params.copy()

        # --- run the task ---
        with pytest.raises(ValueError) as error:
            self.run_task()

        # A wrong token has been given
        assert "401" in str(error.value)


class TestSBMCmd(CommandTestCase):
    @pytest.mark.parametrize(
        "sbm_type, days, nb_results",
        [
            (1, 8, 1),
            (1, 15, 2),
            (2, 8, 0),
            (2, 15, 1),
        ],
    )
    def test_sbm_cmd(self, sbm_type, days, nb_results):
        """
        Dummy test

        :return:
        """

        sbms = getFilteredSbmData(getSbmData(), sbm_type, days)
        assert len(sbms) == nb_results

        # Db migration
        db_upgrade = ["pop", "-ll", "INFO", "db", "upgrade", "heads"]
        self.run_command(db_upgrade)

        # --- Search for SBM1 for the last 8 days ---
        main_command = [
            "pop",
            "-ll",
            "INFO",
            "punk",
            "sbm",
            "-t",
            f"{sbm_type}",
            "-d",
            f"{days}",
            "--token",
            "xxx",
        ]

        print(" ".join(main_command))

        # run the command
        self.run_command(main_command)

        # assert True if everything runs fine
        assert True
