"""
Integration test for payload handlers.
"""

import json
import sys
import os
import pytest
import logging
from unittest.mock import MagicMock
from PySide2.QtWidgets import QApplication

current_path = os.path.abspath(os.getcwd())
root_path = os.path.abspath(current_path + "/NativeUI")
sys.path.append(root_path)

from NativeUI import NativeUI

# remove once all other jsons have been created and imported
TEST_JSON = json.load(
    open(
        os.environ["PYTHONPATH"].split(os.pathsep)[0]
        + "/tests/unittests/fixtures/testSample.json"
    )
)

ALARM_JSON = json.load(
    open(
        os.environ["PYTHONPATH"].split(os.pathsep)[0]
        + "/tests/unittests/fixtures/alarmSample.json"
    )
)
BATTERY_JSON = json.load(
    open(
        os.environ["PYTHONPATH"].split(os.pathsep)[0]
        + "/tests/unittests/fixtures/batterySample.json"
    )
)
CYCLE_JSON = json.load(
    open(
        os.environ["PYTHONPATH"].split(os.pathsep)[0]
        + "/tests/unittests/fixtures/cycleSample.json"
    )
)
DATA_JSON = json.load(
    open(
        os.environ["PYTHONPATH"].split(os.pathsep)[0]
        + "/tests/unittests/fixtures/dataSample.json"
    )
)
PERSONAL_JSON = json.load(
    open(
        os.environ["PYTHONPATH"].split(os.pathsep)[0]
        + "/tests/unittests/fixtures/personalSample.json"
    )
)
READBACK_JSON = json.load(
    open(
        os.environ["PYTHONPATH"].split(os.pathsep)[0]
        + "/tests/unittests/fixtures/readbackSample.json"
    )
)
TARGETS_JSON = json.load(
    open(
        os.environ["PYTHONPATH"].split(os.pathsep)[0]
        + "/tests/unittests/fixtures/targetSample.json"
    )
)

payloads = [ALARM_JSON, BATTERY_JSON, CYCLE_JSON, DATA_JSON, PERSONAL_JSON, READBACK_JSON, TARGETS_JSON]


@pytest.fixture(scope="session", autouse=True)
def myNativeUI():
    if not QApplication.instance():
        app = QApplication(sys.argv)
    else:
        app = QApplication.instance()
    myNativeUI = NativeUI()
    return myNativeUI


def test_battery_payload_registered_battery_handler(myNativeUI, caplog):
    """
    Tests that giving NatviUI.get_updates a battery payload launches the battery handler.
    """
    # Set logging level to debug
    caplog.set_level(logging.DEBUG)

    # give NativeUI a battery payload
    myNativeUI.get_updates(BATTERY_JSON)

    # Run test
    assert "Battery handler" in caplog.text, "The battery payload did not activate the battery handler."

    # Clear logs
    caplog.clear()

    # Test that the other payloads don't trigger battery handler
    payload_subset = [payload for payload in payloads]
    payload_subset.remove(BATTERY_JSON)
    for payload in payload_subset:
        myNativeUI.get_updates(payload)
        assert "Battery handler" not in caplog.text, ("The battery handler was activated by payload:", payload["type"])


def test_cycle_payload_registered_measurement_handler(myNativeUI, caplog):
    """
    Tests that giving NatviUI.get_updates a cycle payload launches the measurement handler.
    """
    # Set logging level to debug
    caplog.set_level(logging.DEBUG)

    # give NativeUI a cycle payload
    myNativeUI.get_updates(CYCLE_JSON)

    # Run test
    assert "Measurement handler" in caplog.text, "The cycle payload did not activate the measurement handler."

    # Clear logs
    caplog.clear()

    # Test that the other payloads don't trigger measurement handler
    payload_subset = [payload for payload in payloads]
    payload_subset.remove(READBACK_JSON)
    payload_subset.remove(CYCLE_JSON)
    for payload in payload_subset:
        myNativeUI.get_updates(payload)
        assert "Measurement handler" not in caplog.text, ("The measurement handler was activated by payload:", payload["type"])


def test_personal_payload_registered_personal_handler(myNativeUI, caplog):
    """
    Tests that giving NatviUI.get_updates a personal payload launches the personal handler.
    """
    # Set logging level to debug
    caplog.set_level(logging.DEBUG)

    # give NativeUI a personal payload
    myNativeUI.get_updates(PERSONAL_JSON)

    # Run test
    assert "Personal handler" in caplog.text, "The personal payload did not activate the personal handler."

    # Clear logs
    caplog.clear()

    # Test that the other payloads don't trigger personal handler
    payload_subset = [payload for payload in payloads]
    payload_subset.remove(PERSONAL_JSON)
    for payload in payload_subset:
        myNativeUI.get_updates(payload)
        assert "Personal handler" not in caplog.text, ("The personal handler was activated by payload:", payload["type"])


def test_data_payload_registered_data_and_alarm_handlers(myNativeUI, caplog):
    """
    Tests that giving NatviUI.get_updates a data payload launches the data and alarm handlers.
    """
    # Set logging level to debug
    caplog.set_level(logging.DEBUG)

    # give NativeUI a personal payload
    myNativeUI.get_updates(DATA_JSON)

    # Run test
    assert "Data handler" and "Alarm handler" in caplog.text, "The data payload did not activate the data and alarm handler(s)."

    # Clear logs
    caplog.clear()

    # Test that the other payloads don't trigger battery handler
    payload_subset = [payload for payload in payloads]
    payload_subset.remove(DATA_JSON)
    payload_subset.remove(ALARM_JSON)
    for payload in payload_subset:
        myNativeUI.get_updates(payload)
        assert "Data handler" and "Alarm handler" not in caplog.text, ("The data handler was activated by payload:", payload["type"])


def test_alarm_payload_registered_alarm_handler(myNativeUI, caplog):
    """
    TTests that giving NatviUI.get_updates a alarm payload launches the alarm handler.
    """
    # Set logging level to debug
    caplog.set_level(logging.DEBUG)

    # give NativeUI a personal payload
    myNativeUI.get_updates(ALARM_JSON)

    # Run test
    assert "Alarm handler" in caplog.text, "The alarm payload did not activate the alarm handler."

    # Clear logs
    caplog.clear()

    # Test that the other payloads don't trigger battery handler
    payload_subset = [payload for payload in payloads]
    payload_subset.remove(ALARM_JSON)
    payload_subset.remove(DATA_JSON)
    for payload in payload_subset:
        myNativeUI.get_updates(payload)
        assert "Alarm handler" not in caplog.text, ("The alarm handler was activated by payload:", payload["type"])


def test_readback_payload_registered_expert_mode_and_measurement_handlers(
    myNativeUI, caplog
):
    """
    Tests that giving NatviUI.get_updates a readback payload launches the expert, mode, and measurement handlers.
    """
    # Set logging level to debug
    caplog.set_level(logging.DEBUG)

    # give NativeUI a personal payload
    myNativeUI.get_updates(READBACK_JSON)

    # Run test
    assert "Expert handler" and "Measurement handler"  in caplog.text, "The readback payload did not activate the expert, or measurement, or mode handler(s)."

    # Clear logs
    caplog.clear()

    # Test that the other payloads don't trigger battery handler
    payload_subset = [payload for payload in payloads]
    payload_subset.remove(READBACK_JSON)
    payload_subset.remove(DATA_JSON)
    payload_subset.remove(TARGETS_JSON)
    payload_subset.remove(CYCLE_JSON)
    for payload in payload_subset:
        myNativeUI.get_updates(payload)
        assert "Expert handler" and "Measurement handler" not in caplog.text, ("The expert, or measurement, or mode handler(s) was activated by payload:", payload["type"])


def test_targets_payload_registered_mode_handler(myNativeUI, caplog):
    """
    Tests that giving NatviUI.get_updates a targets payload launches the mode handler.
    """
    # Set logging level to debug
    caplog.set_level(logging.DEBUG)

    # give NativeUI a personal payload
    myNativeUI.get_updates(TARGETS_JSON)

    # Run test
    assert "Mode handler" in caplog.text, "The targets payload did not activate the mode handler."

    # Clear logs
    caplog.clear()

    # Test that the other payloads don't trigger battery handler
    payload_subset = [payload for payload in payloads]
    payload_subset.remove(TARGETS_JSON)
    payload_subset.remove(READBACK_JSON)
    for payload in payload_subset:
        myNativeUI.get_updates(payload)
        assert "Mode handler" not in caplog.text, ("The mode handler was activated by payload:", payload["type"])
