from constant import *
import threading
from queue import Queue as Pipe
from waiter import Waiter


class First_event_observer(threading.Thread, Waiter):
    blackboard = None
    index = 0

    def __init__(self):
        Waiter.__init__(self)
        threading.Thread.__init__(self)

    def start_all(self, threads):
        for thread in threads:
            thread.start()

    def join_all(self, threads):
        for thread in threads:
            thread.join()

    def run(self):
        while True:
            self.wait_until(event_first_file)
            self.blackboard.mock_filters_first.acquire()
            length = len(self.blackboard.filters_first)
            if length == 0:
                continue
            q_out, threads = self.init_chain()
            q_out = self.build_full_chain(length, q_out, threads)
            self.blackboard.mock_filters_first.release()
            self.start_all(threads)
            self.blackboard.data[half_raw_data] = list()
            while True:
                t = q_out.get()
                if isinstance(t, EOFError):
                    break
                self.blackboard.data[half_raw_data].append(t)
            self.join_all(threads)
            self.blackboard.type_event = event_second_data
            self.blackboard.notify()

    def build_full_chain(self, length, q_out, threads):
        for i in range(1, length):
            q_in = q_out
            q_out = Pipe(maxsize=1)
            th = self.blackboard.filters_first[i]()
            th.q_in = q_in
            th.q_out = q_out
            threads.append(th)
        return q_out

    def init_chain(self):
        threads = list()
        q_in = Pipe(maxsize=1)
        self.fill_first(q_in)
        q_out = Pipe(maxsize=1)
        th = self.blackboard.filters_first[0]()
        th.q_in = q_in
        th.q_out = q_out
        threads.append(th)
        return q_out, threads

    def fill_first(self, q_in):
        with open(self.blackboard.data[name_new], "r") as f:
            q_in.put(f.read())
