# -*- 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)

[((3506, 3608), 'pytest.mark.parametrize', 'pytest.mark.parametrize', (['"""params"""', "[{'mode': 52}, {'quality': 52}, {'lgwin': 52}, {'lgblock': 52}]"], {}), "('params', [{'mode': 52}, {'quality': 52}, {'lgwin':\n    52}, {'lgblock': 52}])\n", (3529, 3608), False, 'import pytest\n'), ((3655, 3725), 'pytest.mark.parametrize', 'pytest.mark.parametrize', (['"""exception_cls"""', '[brotli.Error, brotli.error]'], {}), "('exception_cls', [brotli.Error, brotli.error])\n", (3678, 3725), False, 'import pytest\n'), ((1292, 1367), 'brotli.Compressor', 'brotli.Compressor', ([], {'mode': 'mode', 'quality': 'quality', 'lgwin': 'lgwin', 'lgblock': 'lgblock'}), '(mode=mode, quality=quality, lgwin=lgwin, lgblock=lgblock)\n', (1309, 1367), False, 'import brotli\n'), ((2574, 2649), 'brotli.Compressor', 'brotli.Compressor', ([], {'mode': 'mode', 'quality': 'quality', 'lgwin': 'lgwin', 'lgblock': 'lgblock'}), '(mode=mode, quality=quality, lgwin=lgwin, lgblock=lgblock)\n', (2591, 2649), False, 'import brotli\n'), ((3139, 3147), 'hypothesis.strategies.binary', 'binary', ([], {}), '()\n', (3145, 3147), False, 'from hypothesis.strategies import binary, integers, sampled_from, one_of\n'), ((3339, 3370), 'brotli.Decompressor', 'brotli.Decompressor', (['dictionary'], {}), '(dictionary)\n', (3358, 3370), False, 'import brotli\n'), ((3388, 3429), 'brotli.compress', 'brotli.compress', (['s'], {'dictionary': 'dictionary'}), '(s, dictionary=dictionary)\n', (3403, 3429), False, 'import brotli\n'), ((3252, 3260), 'hypothesis.strategies.binary', 'binary', ([], {}), '()\n', (3258, 3260), False, 'from hypothesis.strategies import binary, integers, sampled_from, one_of\n'), ((3262, 3270), 'hypothesis.strategies.binary', 'binary', ([], {}), '()\n', (3268, 3270), False, 'from hypothesis.strategies import binary, integers, sampled_from, one_of\n'), ((619, 659), 'hypothesis.strategies.integers', 'integers', ([], {'min_value': '(1)', 'max_value': '(2 ** 12)'}), '(min_value=1, max_value=2 ** 12)\n', (627, 659), False, 'from hypothesis.strategies import binary, integers, sampled_from, one_of\n'), ((726, 761), 'hypothesis.strategies.integers', 'integers', ([], {'min_value': '(0)', 'max_value': '(11)'}), '(min_value=0, max_value=11)\n', (734, 761), False, 'from hypothesis.strategies import binary, integers, sampled_from, one_of\n'), ((773, 809), 'hypothesis.strategies.integers', 'integers', ([], {'min_value': '(10)', 'max_value': '(24)'}), '(min_value=10, max_value=24)\n', (781, 809), False, 'from hypothesis.strategies import binary, integers, sampled_from, one_of\n'), ((1825, 1865), 'hypothesis.strategies.integers', 'integers', ([], {'min_value': '(1)', 'max_value': '(2 ** 12)'}), '(min_value=1, max_value=2 ** 12)\n', (1833, 1865), False, 'from hypothesis.strategies import binary, integers, sampled_from, one_of\n'), ((1932, 1967), 'hypothesis.strategies.integers', 'integers', ([], {'min_value': '(0)', 'max_value': '(11)'}), '(min_value=0, max_value=11)\n', (1940, 1967), False, 'from hypothesis.strategies import binary, integers, sampled_from, one_of\n'), ((1979, 2015), 'hypothesis.strategies.integers', 'integers', ([], {'min_value': '(10)', 'max_value': '(24)'}), '(min_value=10, max_value=24)\n', (1987, 2015), False, 'from hypothesis.strategies import binary, integers, sampled_from, one_of\n'), ((3794, 3822), 'pytest.raises', 'pytest.raises', (['exception_cls'], {}), '(exception_cls)\n', (3807, 3822), False, 'import pytest\n'), ((3832, 3859), 'brotli.Compressor', 'brotli.Compressor', ([], {}), '(**params)\n', (3849, 3859), False, 'import brotli\n'), ((532, 566), 'brotli.compress', 'brotli.compress', (['uncompressed_data'], {}), '(uncompressed_data)\n', (547, 566), False, 'import brotli\n'), ((839, 873), 'hypothesis.strategies.integers', 'integers', ([], {'min_value': '(0)', 'max_value': '(0)'}), '(min_value=0, max_value=0)\n', (847, 873), False, 'from hypothesis.strategies import binary, integers, sampled_from, one_of\n'), ((883, 919), 'hypothesis.strategies.integers', 'integers', ([], {'min_value': '(16)', 'max_value': '(24)'}), '(min_value=16, max_value=24)\n', (891, 919), False, 'from hypothesis.strategies import binary, integers, sampled_from, one_of\n'), ((2045, 2079), 'hypothesis.strategies.integers', 'integers', ([], {'min_value': '(0)', 'max_value': '(0)'}), '(min_value=0, max_value=0)\n', (2053, 2079), False, 'from hypothesis.strategies import binary, integers, sampled_from, one_of\n'), ((2089, 2125), 'hypothesis.strategies.integers', 'integers', ([], {'min_value': '(16)', 'max_value': '(24)'}), '(min_value=16, max_value=24)\n', (2097, 2125), False, 'from hypothesis.strategies import binary, integers, sampled_from, one_of\n'), ((3218, 3236), 'brotli.compress', 'brotli.compress', (['s'], {}), '(s)\n', (3233, 3236), False, 'import brotli\n')]