from web_stream_downloader.packet.directory import PacketDirectory
from web_stream_downloader.packet.error import PacketError
from web_stream_downloader.packet.file_chunk import PacketFileChunk
from web_stream_downloader.packet.file_continue import PacketFileContinue
from web_stream_downloader.packet.file_end import PacketFileEnd
from web_stream_downloader.packet.file_start import PacketFileStart
from web_stream_downloader.packet.stream_end import PacketStreamEnd
from web_stream_downloader.packet.symlink import PacketSymlink
from web_stream_downloader.packet_type import PacketType
from web_stream_downloader.stream_packet_readers.base_stream_packet_reader import BaseStreamPacketReader


class PlainStreamPacketReader(BaseStreamPacketReader):
    def iter_packets(self):
        while True:
            packet_type = self._read_line()

            if packet_type == '':
                break

            packet_type = int(packet_type)

            if packet_type == PacketType.DIRECTORY:
                length = int(self._read_line())
                name = self._read_bytes(length)
                yield PacketDirectory(name)
            elif packet_type == PacketType.FILE_START:
                length = int(self._read_line())
                name = self._read_bytes(length)
                yield PacketFileStart(name)
            elif packet_type == PacketType.FILE_CONTINUE:
                start_position = int(self._read_line())
                file_path_length = int(self._read_line())
                file_path = self._read_bytes(file_path_length)
                yield PacketFileContinue(start_position, file_path)
            elif packet_type == PacketType.FILE_CHUNK:
                length = int(self._read_line())
                data = self._read_bytes(length)
                yield PacketFileChunk(data)
            elif packet_type == PacketType.FILE_END:
                yield PacketFileEnd()
            elif packet_type == PacketType.SYMLINK:
                symlink_path_length = int(self._read_line())
                symlink_path = self._read_bytes(symlink_path_length)
                target_length = int(self._read_line())
                target = self._read_bytes(target_length)
                yield PacketSymlink(symlink_path, target)
            elif packet_type == PacketType.ERROR:
                message_length = int(self._read_line())
                message = self._read_bytes(message_length)
                yield PacketError(message)
            elif packet_type == PacketType.STREAM_END:
                yield PacketStreamEnd()
            else:
                raise Exception('Invalid packet type %s' % packet_type)
