# -*- coding: utf-8 -*-
"""
test_simple_compression
~~~~~~~~~~~~~~~~~~~~~~~~~

Tests for compression of single chunks.
"""
import brotli

import pytest

from hypothesis import given
from hypothesis.strategies import binary, integers, sampled_from, one_of


def test_roundtrip_compression_with_files(simple_compressed_file):
    """
    Roundtripping data through the compressor works correctly.
    """
    with open(simple_compressed_file[0], 'rb') as f:
        uncompressed_data = f.read()

    assert brotli.decompress(
        brotli.compress(uncompressed_data)
    ) == uncompressed_data


@given(
    chunk_size=integers(min_value=1, max_value=2**12),
    mode=sampled_from(list(brotli.BrotliEncoderMode)),
    quality=integers(min_value=0, max_value=11),
    lgwin=integers(min_value=10, max_value=24),
    lgblock=one_of(
        integers(min_value=0, max_value=0),
        integers(min_value=16, max_value=24)
    ),
)
def test_streaming_compression(one_compressed_file,
                               chunk_size,
                               mode,
                               quality,
                               lgwin,
                               lgblock):
    """
    Confirm that the streaming compressor works as expected.
    """
    compressed_chunks = []
    c = brotli.Compressor(
        mode=mode, quality=quality, lgwin=lgwin, lgblock=lgblock
    )
    with open(one_compressed_file, 'rb') as f:
        while True:
            next_data = f.read(chunk_size)
            if not next_data:
                break

            compressed_chunks.append(c.compress(next_data))

    compressed_chunks.append(c.finish())
    decompressed = brotli.decompress(b''.join(compressed_chunks))
    with open(one_compressed_file, 'rb') as f:
        assert decompressed == f.read()


@given(
    chunk_size=integers(min_value=1, max_value=2**12),
    mode=sampled_from(list(brotli.BrotliEncoderMode)),
    quality=integers(min_value=0, max_value=11),
    lgwin=integers(min_value=10, max_value=24),
    lgblock=one_of(
        integers(min_value=0, max_value=0),
        integers(min_value=16, max_value=24)
    ),
)
def test_streaming_compression_flush(one_compressed_file,
                                     chunk_size,
                                     mode,
                                     quality,
                                     lgwin,
                                     lgblock):
    """
    Confirm that the streaming compressor works as expected, including flushes
    after each chunk.
    """
    compressed_chunks = []
    c = brotli.Compressor(
        mode=mode, quality=quality, lgwin=lgwin, lgblock=lgblock
    )
    with open(one_compressed_file, 'rb') as f:
        while True:
            next_data = f.read(chunk_size)
            if not next_data:
                break

            compressed_chunks.append(c.compress(next_data))
            compressed_chunks.append(c.flush())

    compressed_chunks.append(c.finish())
    decompressed = brotli.decompress(b''.join(compressed_chunks))
    with open(one_compressed_file, 'rb') as f:
        assert decompressed == f.read()


@given(binary())
def test_compressed_data_roundtrips(s):
    assert brotli.decompress(brotli.compress(s)) == s


@given(binary(), binary())
def test_compressed_data_with_dictionaries(s, dictionary):
    d = brotli.Decompressor(dictionary)
    compressed = brotli.compress(s, dictionary=dictionary)
    uncompressed = d.decompress(compressed)
    assert uncompressed == s


@pytest.mark.parametrize(
    "params",
    [
        {"mode": 52},
        {"quality": 52},
        {"lgwin": 52},
        {"lgblock": 52},
    ]
)
@pytest.mark.parametrize("exception_cls", [brotli.Error, brotli.error])
def test_bad_compressor_parameters(params, exception_cls):
    with pytest.raises(exception_cls):
        brotli.Compressor(**params)

[((117, 1, 125, 1), 'pytest.mark.parametrize', 'pytest.mark.parametrize', ({(118, 4, 118, 12): '"""params"""', (119, 4, 124, 5): "[{'mode': 52}, {'quality': 52}, {'lgwin': 52}, {'lgblock': 52}]"}, {}), "('params', [{'mode': 52}, {'quality': 52}, {'lgwin':\n    52}, {'lgblock': 52}])", False, 'import pytest\n'), ((126, 1, 126, 71), 'pytest.mark.parametrize', 'pytest.mark.parametrize', ({(126, 25, 126, 40): '"""exception_cls"""', (126, 42, 126, 70): '[brotli.Error, brotli.error]'}, {}), "('exception_cls', [brotli.Error, brotli.error])", False, 'import pytest\n'), ((48, 8, 50, 5), 'brotli.Compressor', 'brotli.Compressor', (), '', False, 'import brotli\n'), ((86, 8, 88, 5), 'brotli.Compressor', 'brotli.Compressor', (), '', False, 'import brotli\n'), ((104, 7, 104, 15), 'hypothesis.strategies.binary', 'binary', ({}, {}), '()', False, 'from hypothesis.strategies import binary, integers, sampled_from, one_of\n'), ((111, 8, 111, 39), 'brotli.Decompressor', 'brotli.Decompressor', ({(111, 28, 111, 38): 'dictionary'}, {}), '(dictionary)', False, 'import brotli\n'), ((112, 17, 112, 58), 'brotli.compress', 'brotli.compress', (), '', False, 'import brotli\n'), ((109, 7, 109, 15), 'hypothesis.strategies.binary', 'binary', ({}, {}), '()', False, 'from hypothesis.strategies import binary, integers, sampled_from, one_of\n'), ((109, 17, 109, 25), 'hypothesis.strategies.binary', 'binary', ({}, {}), '()', False, 'from hypothesis.strategies import binary, integers, sampled_from, one_of\n'), ((29, 15, 29, 53), 'hypothesis.strategies.integers', 'integers', (), '', False, 'from hypothesis.strategies import binary, integers, sampled_from, one_of\n'), ((31, 12, 31, 47), 'hypothesis.strategies.integers', 'integers', (), '', False, 'from hypothesis.strategies import binary, integers, sampled_from, one_of\n'), ((32, 10, 32, 46), 'hypothesis.strategies.integers', 'integers', (), '', False, 'from hypothesis.strategies import binary, integers, sampled_from, one_of\n'), ((66, 15, 66, 53), 'hypothesis.strategies.integers', 'integers', (), '', False, 'from hypothesis.strategies import binary, integers, sampled_from, one_of\n'), ((68, 12, 68, 47), 'hypothesis.strategies.integers', 'integers', (), '', False, 'from hypothesis.strategies import binary, integers, sampled_from, one_of\n'), ((69, 10, 69, 46), 'hypothesis.strategies.integers', 'integers', (), '', False, 'from hypothesis.strategies import binary, integers, sampled_from, one_of\n'), ((128, 9, 128, 37), 'pytest.raises', 'pytest.raises', ({(128, 23, 128, 36): 'exception_cls'}, {}), '(exception_cls)', False, 'import pytest\n'), ((129, 8, 129, 35), 'brotli.Compressor', 'brotli.Compressor', ({}, {}), '(**params)', False, 'import brotli\n'), ((24, 8, 24, 42), 'brotli.compress', 'brotli.compress', ({(24, 24, 24, 41): 'uncompressed_data'}, {}), '(uncompressed_data)', False, 'import brotli\n'), ((34, 8, 34, 42), 'hypothesis.strategies.integers', 'integers', (), '', False, 'from hypothesis.strategies import binary, integers, sampled_from, one_of\n'), ((35, 8, 35, 44), 'hypothesis.strategies.integers', 'integers', (), '', False, 'from hypothesis.strategies import binary, integers, sampled_from, one_of\n'), ((71, 8, 71, 42), 'hypothesis.strategies.integers', 'integers', (), '', False, 'from hypothesis.strategies import binary, integers, sampled_from, one_of\n'), ((72, 8, 72, 44), 'hypothesis.strategies.integers', 'integers', (), '', False, 'from hypothesis.strategies import binary, integers, sampled_from, one_of\n'), ((106, 29, 106, 47), 'brotli.compress', 'brotli.compress', ({(106, 45, 106, 46): 's'}, {}), '(s)', False, 'import brotli\n')]