from durus.utils import as_bytes
from qp.fill.static import FileStream
from sancho.utest import raises
from sancho.utest import UTest
from tempfile import NamedTemporaryFile
import os

ascii_lowercase = as_bytes('abcdefghijklmnopqrstuvwxyz')

class StaticFileTest (UTest):

    def _pre(self):
        self.temp_file = NamedTemporaryFile()
        self.temp_file.write(ascii_lowercase)
        self.temp_file.flush()

    def _post(self):
        self.temp_file.close()

    def _eat_stream(self, stream):
        chunks = []
        for chunk in stream:
            chunks.append(as_bytes(chunk))
        return as_bytes("").join(chunks)
            
    def test_static_file(self):
        stream = FileStream(open(self.temp_file.name))
        result = self._eat_stream(stream)
        assert result == ascii_lowercase, (result, ascii_lowercase)

    def test_static_file_with_size(self):
        stat = os.stat(self.temp_file.name)
        stream = FileStream(open(self.temp_file.name), stat.st_size)
        result = self._eat_stream(stream)
        assert result == ascii_lowercase

    def test_static_file_range1(self):
        stream = FileStream(open(self.temp_file.name))
        stream.set_range((0, None))
        raises(ValueError, self._eat_stream, stream)

    def test_static_file_range2(self):
        stat = os.stat(self.temp_file.name)
        stream = FileStream(open(self.temp_file.name), stat.st_size)
        stream.set_range((0, None))
        result = self._eat_stream(stream)
        assert result == ascii_lowercase

    def test_static_file_range3(self):
        stat = os.stat(self.temp_file.name)
        stream = FileStream(open(self.temp_file.name), stat.st_size)
        stream.set_range((5, None))
        result = self._eat_stream(stream)
        assert result == ascii_lowercase[5:]

    def test_static_file_range4(self):
        stream = FileStream(open(self.temp_file.name))
        stream.set_range((None, len(ascii_lowercase)))
        raises(ValueError, self._eat_stream, stream)

    def test_static_file_range5(self):
        stat = os.stat(self.temp_file.name)
        stream = FileStream(open(self.temp_file.name), stat.st_size)
        stream.set_range((None, len(ascii_lowercase)))
        result = self._eat_stream(stream)
        assert result == ascii_lowercase

    def test_static_file_range6(self):
        stat = os.stat(self.temp_file.name)
        stream = FileStream(open(self.temp_file.name), stat.st_size)
        stream.set_range((None, 5))
        result = self._eat_stream(stream)
        assert result == ascii_lowercase[-5:]

    def test_static_file_range6_1(self):
        FileStream.CHUNK_SIZE=3
        stat = os.stat(self.temp_file.name)
        stream = FileStream(open(self.temp_file.name), stat.st_size)
        stream.set_range((None, 5))
        result = self._eat_stream(stream)
        assert result == ascii_lowercase[-5:]
        FileStream.CHUNK_SIZE=20000

    def test_static_file_range7(self):
        stat = os.stat(self.temp_file.name)
        stream = FileStream(open(self.temp_file.name), stat.st_size)
        stream.set_range((4, 5))
        result = self._eat_stream(stream)
        assert result == ascii_lowercase[4:6]

    def test_static_file_range8(self): 	
        FileStream.CHUNK_SIZE=3
        stat = os.stat(self.temp_file.name)
        stream = FileStream(open(self.temp_file.name), stat.st_size)
        stream.set_range((4, 5))
        result = self._eat_stream(stream)
        assert result == ascii_lowercase[4:6]
        FileStream.CHUNK_SIZE=20000

    def test_static_file_range9(self): 	
        FileStream.CHUNK_SIZE=3
        stat = os.stat(self.temp_file.name)
        stream = FileStream(open(self.temp_file.name), stat.st_size)
        stream.set_range((4, 8))
        result = self._eat_stream(stream)
        assert result == ascii_lowercase[4:9]
        FileStream.CHUNK_SIZE=20000

    def test_static_file_range10(self): 	
        FileStream.CHUNK_SIZE=3
        stream = FileStream(open(self.temp_file.name))
        stream.set_range((4, 5))
        result = self._eat_stream(stream)
        assert result == ascii_lowercase[4:6]
        FileStream.CHUNK_SIZE=20000

    def test_static_file_range11(self): 	
        FileStream.CHUNK_SIZE=3
        stream = FileStream(open(self.temp_file.name))
        stream.set_range((4, 8))
        result = self._eat_stream(stream)
        assert result == ascii_lowercase[4:9]
        FileStream.CHUNK_SIZE=20000

if __name__ == "__main__":
    StaticFileTest()
