import pandas as pd
import time
from queue import Empty
from threading import Lock
import threading as th
import logging
logger = logging.getLogger(__name__)


def records_to_df(records):
    records = pd.DataFrame.from_records(records)
    records['receive_ts'] = records['send_ts'] + records['interval_real'] / 1e6
    records['receive_sec'] = records.receive_ts.astype(int)
    # TODO: consider configuration for the following:
    records['tag'] = records.tag.str.rsplit('#', 1, expand=True)[0]
    records.set_index(['receive_sec'], inplace=True)
    return records


class BfgReader(object):
    def __init__(self, results, closed):
        self.buffer = ""
        self.stat_buffer = ""
        self.results = results
        self.closed = closed
        self.records = []
        self.lock = Lock()
        self.thread = th.Thread(target=self._cacher)
        self.thread.start()

    def _cacher(self):
        while True:
            try:
                self.records.append(
                    self.results.get(block=False))
            except Empty:
                if not self.closed.is_set():
                    time.sleep(0.1)
                else:
                    break

    def __next__(self):
        if self.closed.is_set():
            self.thread.join()
            raise StopIteration
        with self.lock:
            records = self.records
            self.records = []
        if records:
            return records_to_df(records)
        return None

    def __iter__(self):
        return self
