from flask import current_app

from extensions import db
from Copilot.dataAcquisition.Core.BaseSubscriber import BaseSubscriber
from models.factory_structure_model import Parameter, Machine
from Copilot.dataAcquisition.Core.CollectedData import CollectedData, ParameterRef, MachineRef
from Copilot.dataAcquisition.Core.eventBus import EventBus
from Copilot.dataAcquisition.Utils.dataclassUtils import *

class centralDataCollector(BaseSubscriber):
    def __init__(self, event_bus:EventBus, app=None):

        super().__init__()

        if app is None:
            app =  current_app._get_current_object()
        self.app = app

        self.event_bus = event_bus

        self.parameter_map:dict[str, ParameterRef] = {}
        self.machine_map:dict[str, MachineRef] = {}
        self.parameter2machine_map:dict[str, MachineRef] = {}

        self.generate_parameters_map()
        self.generate_machines_map()
        self.generate_parameter2machine_map()

    def generate_parameters_map(self):
        self.parameter_map = {}
        with self.app.app_context():

            parameters:list[Parameter] = Parameter.query.all()
            for p in parameters:
                self.parameter_map[p.tag] = parm_model_to_dataclass(p)
          
                
       

    def generate_machines_map(self):
        self.machine_map = {}
        with self.app.app_context():

            machines:list[Machine] = Machine.query.all()
            for m in machines:
                self.machine_map[m.id] = machine_model_to_dataclass(m)

            
        

    def generate_parameter2machine_map(self,):
        
        self.parameter2machine_map = {}
        for p in self.parameter_map.values():
            p_id = p.id
            m_id = p.machine_id
            machine = self.machine_map.get(m_id)

            self.parameter2machine_map[p_id] = machine
           

    
    def handle(self, event:CollectedData):
        parameter = self.parameter_map.get(event.tag)

        if not parameter:
            return
        event.parameter = parameter

        machine = self.parameter2machine_map.get(event.parameter.id)
        if not machine:
            return
        event.machine = machine

        self.event_bus.emit(event)