import warnings

from UniTAP.dev.modules.capturer.result_object import ResultObject
from UniTAP.libs.lib_tsi.tsi import TSIEventParser
from .event_utils import save_to_bin_file, save_to_csv_file, save_to_txt_file, save_to_html_file
from .event_types import EventFileFormat


class ResultEventObject(ResultObject):
    """
    Class `ResultEventObject` inherited from class `ResultObject`.
    Class `ResultEventObject` allows saving captured events to file `save_to_file_selected_event` or
    `save_to_file_all_events`.
    Also has all the `ResultObject` functionality.
    """

    def __init__(self, fw_info: dict):
        super().__init__()
        self.__parsed_buffer = []
        self.__fw_info = fw_info
        self.__long_type_string = False

    def __str__(self):
        return f"Start capture time: {self.start_capture_time}\n" \
               f"End capture time: {self.end_capture_time}\n" \
               f"Timestamp: {self.timestamp.__str__()}\n"

    def save_to_file_selected_event(self, file_format: EventFileFormat, path: str, index: int):
        """

        Saving selected event to file. Supported file formats describe in `EventFileFormat`.

        Args:
            file_format (`PictureFileFormat`) - file format
            path (str) - path to save
            index (int) - number of event in list
        """
        if len(self.buffer) > 0:
            if file_format == EventFileFormat.BIN:
                save_to_bin_file(path=path, events=self.buffer, index=index)
            elif file_format == EventFileFormat.TXT:
                if len(self.__parsed_buffer) == 0:
                    self.__parse_buffer()
                save_to_txt_file(path=path, events=self.__parsed_buffer, index=index)
            elif file_format == EventFileFormat.HTML:
                raise NotImplementedError('Temporary not supported to txt files.')
            else:
                raise ValueError(f"Incorrect file format. Available formats: "
                                 f"{EventFileFormat.BIN.name}, {EventFileFormat.TXT.name}, "
                                 f"{EventFileFormat.HTML.name}.\n"
                                 f"Transferred audio format: {file_format.name}")
            self.__parsed_buffer.clear()
        else:
            warnings.warn("Buffer size is equal 0.")

    def save_to_file_all_events(self, file_format: EventFileFormat, path: str):
        """

        Saving all events to file. Supported file formats describe in `EventFileFormat`.

        Args:
            file_format (`EventFileFormat`) - file format
            path (str) - path to save
        """
        if len(self.buffer) > 0:
            if file_format == EventFileFormat.BIN:
                if path.find(".bin") == -1:
                    path += ".bin"
                save_to_bin_file(path=path, events=self.buffer)
            elif file_format == EventFileFormat.CSV:
                if path.find(".csv") == -1:
                    path += ".csv"
                if len(self.__parsed_buffer) == 0:
                    self.__parse_buffer()
                save_to_csv_file(path=path, events=self.__parsed_buffer)
            elif file_format == EventFileFormat.TXT:
                if path.find(".txt") == -1:
                    path += ".txt"
                if len(self.__parsed_buffer) == 0:
                    self.__parse_buffer()
                save_to_txt_file(path=path, events=self.__parsed_buffer)
            elif file_format == EventFileFormat.HTML:
                if path.find(".html") == -1:
                    path += ".html"
                if len(self.__parsed_buffer) == 0:
                    self.__parse_buffer()
                save_to_html_file(path=path, events=self.__parsed_buffer, fw_info=self.__fw_info,
                                  long_type_string=self.__long_type_string)
            else:
                raise ValueError(f"Incorrect file format. Available formats: "
                                 f"{EventFileFormat.BIN.name}, {EventFileFormat.TXT.name}, "
                                 f"{EventFileFormat.HTML.name}.\n"
                                 f"Transferred audio format: {file_format.name}")
            self.__parsed_buffer.clear()
        else:
            warnings.warn("Buffer size is equal 0.")

    def __parse_buffer(self):
        with TSIEventParser() as parser:
            for index, item in enumerate(self.buffer):
                if len(item.data) > 12:
                    res = parser.parse(item.data, to_dict=True)
                    if res[0] < 0:
                        warnings.warn(f"Cannot parse element {index}. Error {res[0]}")
                    else:
                        self.__parsed_buffer.append(res[1])
                        if len(res[1].get('type')) > 8 and self.__long_type_string is False:
                            self.__long_type_string = True
