from unittest import mock
import pytest
from opentrons.protocols.parse import parse
from opentrons.protocols.execution.execute_json_v4 import (
    dispatch_json, _engage_magnet, _disengage_magnet, load_modules_from_json,
    _temperature_module_set_temp,
    _temperature_module_deactivate,
    _temperature_module_await_temp,
    _thermocycler_close_lid,
    _thermocycler_open_lid,
    _thermocycler_deactivate_block,
    _thermocycler_deactivate_lid,
    _thermocycler_set_block_temperature,
    _thermocycler_set_lid_temperature,
    _thermocycler_run_profile,
    assert_no_async_tc_behavior,
    assert_tc_commands_do_not_use_unimplemented_params,
    TC_SPANNING_SLOT)
import opentrons.protocols.execution.execute_json_v4 as v4
from opentrons.protocol_api import (
    MagneticModuleContext, TemperatureModuleContext, ThermocyclerContext,
    ProtocolContext)
from opentrons.protocols.execution import execute
from opentrons_shared_data.protocol.constants import (
    JsonPipetteCommand as JPC,
    JsonMagneticModuleCommand as JMMC,
    JsonTemperatureModuleCommand as JTMC,
    JsonThermocyclerCommand as JTHC
)


# autouse set to True to setup/teardown mock after each run
@pytest.fixture(autouse=True)
def mockObj():
    m = mock.Mock()
    yield m
    m.reset()


@pytest.fixture
def pipette_command_map(mockObj):
    mock_pipette_command_map = {
        JPC.blowout.value: mockObj._blowout,
        JPC.pickUpTip.value: mockObj._pick_up_tip,
        JPC.dropTip.value: mockObj._drop_tip,
        JPC.aspirate.value: mockObj._aspirate,
        JPC.dispense.value: mockObj._dispense,
        JPC.touchTip.value: mockObj._touch_tip,
    }
    return mock_pipette_command_map


@pytest.fixture
def magnetic_module_command_map(mockObj):
    mock_magnetic_module_command_map = {
        JMMC.magneticModuleEngageMagnet.value:
        mockObj._engage_magnet,
        JMMC.magneticModuleDisengageMagnet.value:
        mockObj._disengage_magnet,
    }

    return mock_magnetic_module_command_map


@pytest.fixture
def temperature_module_command_map(mockObj):
    mock_temperature_module_command_map = {
        JTMC.temperatureModuleSetTargetTemperature.value:
        mockObj._temperature_module_set_temp,
        JTMC.temperatureModuleDeactivate.value:
        mockObj._temperature_module_deactivate,
        JTMC.temperatureModuleAwaitTemperature.value:
        mockObj._temperature_module_await_temp
    }
    return mock_temperature_module_command_map


@pytest.fixture
def thermocycler_module_command_map(mockObj):
    mock_thermocycler_module_command_map = {
        JTHC.thermocyclerCloseLid.value:
            mockObj._thermocycler_close_lid,
        JTHC.thermocyclerOpenLid.value:
            mockObj._thermocycler_open_lid,
        JTHC.thermocyclerDeactivateBlock.value:
            mockObj._thermocycler_deactivate_block,
        JTHC.thermocyclerDeactivateLid.value:
            mockObj._thermocycler_deactivate_lid,