# author Aaron Moser, Theresa Herr

import datetime
import threading
from heater_instance_interface import HeaterInstanceInterface
from database_interface import DatabaseInterface
from global_outcome import GlobalOutcome
from simulation import Simulation
import tasks.daily_task
import tasks.realtime_task

class HeaterInstanceWorkerThread(threading.Thread):

    def __init__(self, global_outcome: GlobalOutcome, mode: Simulation.Mode, heater_instance_interface: HeaterInstanceInterface, start_date: datetime.datetime, end_date: datetime.datetime, database_interface: DatabaseInterface):
        super().__init__()
        self.global_outcome: GlobalOutcome = global_outcome
        self.__mode: Simulation.Mode = mode
        self._stop_event: threading.Event = threading.Event()
        self.heater_instance_interface: HeaterInstanceInterface = heater_instance_interface
        self.start_date: datetime.datetime = start_date
        self.end_date: datetime.datetime = end_date
        self.db_interface: DatabaseInterface = database_interface

    def run(self):
        while not self._stop_event.is_set():
            match self.__mode:
                case Simulation.Mode.REALTIME:
                    tasks.realtime_task.realtime_task(self.global_outcome, self.heater_instance_interface, self.start_date, self.end_date, self.save_outcome)
                case Simulation.Mode.DAILY:
                    tasks.daily_task.daily_task(self.global_outcome, self.heater_instance_interface, self.start_date, self.end_date, self.save_outcome)
                case _:
                    print("Error unknown mode.")
                            
    def get_instance_interface(self) -> HeaterInstanceInterface:
        return self.heater_instance_interface

    def stop(self):
        self.heater_instance_interface.close()
        self._stop_event.set()

    def get_stop_event_state(self) -> bool:
        return self._stop_event.is_set()

    def save_outcome(self, outcome_list: list):
        for outcome in outcome_list:
            self.db_interface.insert_task_outcome(outcome)