# Generated by sila2.code_generator; sila2.__version__: 0.12.2
from __future__ import annotations

import string
from typing import TYPE_CHECKING

from sila2.server import MetadataDict

from ..generated.sessionmanagement import (
    SessionCreate_Responses,
    SessionDelete_Responses,
    SessionManagementBase,
)

if TYPE_CHECKING:
    from ..server import Server

import opentrons.execute
import opentrons.simulate
import uuid

from ..base import Base
from ..labware.labware_wrapper import LabwareWrapper


class SessionManagementImpl(SessionManagementBase):
    def __init__(self, parent_server: Server, base: Base, simulate: bool=False) -> None:
        super().__init__(parent_server=parent_server)
        self.base = base
        self.should_simulate = simulate

    def SessionCreate(self, *,
                      metadata: MetadataDict) -> SessionCreate_Responses:
        new_id = self.base.start_session()
        if new_id != "":
            if self.should_simulate:
                protocol = opentrons.simulate.get_protocol_api("2.19", robot_type="Flex")
            else:
                protocol = opentrons.execute.get_protocol_api("2.19")
            tiprack = protocol.load_labware(
                load_name="opentrons_flex_96_tiprack_1000ul", location="A2"
            )
            # attach pipette to left mount
            pipette = protocol.load_instrument(
                instrument_name="flex_8channel_1000",
                mount="left",
                tip_racks=[tiprack]
            )
            trash = protocol.load_trash_bin(location="A3")
            self.base.set_instrument(pipette)
            self.base.set_session_protocol(protocol)
            self.base.add_labware(LabwareWrapper(tiprack, "A2"),
                                  str(uuid.uuid4()))
            self.base.set_trash(trash)
            return SessionCreate_Responses(SessionToken=new_id)
        raise Exception("Machine is already in use")

    def SessionDelete(self, SessionToken: str, *,
                      metadata: MetadataDict) -> SessionDelete_Responses:
        self.base.end_session(SessionToken)
        return SessionDelete_Responses()
