# -*- coding: utf-8 -*-

import pytest
from .test_base_class import TestBaseClass

try:
    from collections import Counter
except ImportError:
    from counter26 import Counter

import aerospike
from aerospike_helpers.operations import operations


class TestCompress:

    config = TestBaseClass.get_connection_config()

    pytestmark = pytest.mark.skipif(
        not TestBaseClass.enterprise_in_use(), reason="No enterprise hosts, maybe cluster is not enterprise."
    )

    @pytest.fixture(autouse=True)
    def setup(self, request, as_connection):
        self.keys = []

        for i in range(5):
            key = ("test", "demo", i)
            rec = {"name": "name%s" % (str(i)), "age": i}
            as_connection.put(key, rec)
            self.keys.append(key)

        key = ("test", "demo", "float_value")
        as_connection.put(key, {"float_value": 4.3})
        self.keys.append(key)

        def teardown():
            """
            Teardown method.
            """
            for i in range(5):
                key = ("test", "demo", i)
                as_connection.remove(key)

            key = ("test", "demo", "float_value")
            as_connection.remove(key)

        request.addfinalizer(teardown)

    def test_put_get_with_compress_policy(self):
        """
        Invoke put() and get() with compression policy.
        """
        key = ("test", "demo", 1)
        expected = "john" * (5 * 1024)
        rec = {"val": expected}

        policy = {"compress": True}

        self.as_connection.put(key, rec, policy)
        _, _, bins = self.as_connection.get(key, policy)

        assert bins["val"] == expected

    def test_batch_with_compress_policy(self):
        policy = {"compress": True}
        records = self.as_connection.batch_read(self.keys, policy=policy)

        assert isinstance(records.batch_records, list)
        assert len(records.batch_records) == 6
        assert Counter([br.key[2] for br in records.batch_records]) == Counter([0, 1, 2, 3, 4, "float_value"])
        assert records.batch_records[5].record[2] == {"float_value": 4.3}

    def test_operate_with_compress_policy(self):
        """
        Invoke operate() with compression policy.
        """
        key = ("test", "demo", 1)
        policy = {
            "key": aerospike.POLICY_KEY_SEND,
            "compress": True,
        }

        llist = [
            operations.append("name", "aa"),
            operations.increment("age", 3),
            operations.read("name")
        ]

        key, _, bins = self.as_connection.operate(key, llist, {}, policy)

        assert bins == {"name": "name1aa"}
        assert key == (
            "test",
            "demo",
            1,
            bytearray(b"\xb7\xf4\xb88\x89\xe2\xdag\xdeh>\x1d\xf6\x91\x9a\x1e\xac\xc4F\xc8"),
        )

    def test_read_with_compress_policy(self, put_data):
        """
        Invoke get() for a record with compression policy.
        """
        key = ("test", "demo", 1)
        rec = {"name": "john", "age": 1}

        policy = {"key": aerospike.POLICY_KEY_SEND, "compress": True}

        self.as_connection.put(key, rec, policy)

        key, _, bins = self.as_connection.get(key, policy)

        assert bins == {"name": "john", "age": 1}
        assert key == (
            "test",
            "demo",
            1,
            bytearray(b"\xb7\xf4\xb88\x89\xe2\xdag\xdeh>\x1d\xf6\x91\x9a\x1e\xac\xc4F\xc8"),
        )

    def test_scan_with_compress_policy(self):
        """
        Invoke execute_background() for a scan with compression enabled.
        """

        ops = [operations.touch()]

        scan_obj = self.as_connection.scan("test", "demo")
        scan_obj.add_ops(ops)
        scan_obj.execute_background({"compress": True})
