# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from collections import OrderedDict
from decimal import Decimal

import pytest

from pyignite import GenericObjectMeta
from pyignite.datatypes import (
    BoolObject, DecimalObject, FloatObject, IntObject, String,
)
from pyignite.datatypes.prop_codes import *
from pyignite.exceptions import CacheError, ParameterError


def test_cache_create(client):
    cache = client.get_or_create_cache('my_oop_cache')
    assert cache.name == cache.settings[PROP_NAME] == 'my_oop_cache'
    cache.destroy()


def test_cache_remove(client):
    cache = client.get_or_create_cache('my_cache')
    cache.clear()
    assert cache.get_size() == 0

    cache.put_all({
        'key_1': 1,
        'key_2': 2,
        'key_3': 3,
        'key_4': 4,
        'key_5': 5,
    })
    assert cache.get_size() == 5

    result = cache.remove_if_equals('key_1', 42)
    assert result is False
    assert cache.get_size() == 5

    result = cache.remove_if_equals('key_1', 1)
    assert result is True
    assert cache.get_size() == 4

    cache.remove_keys(['key_1', 'key_3', 'key_5', 'key_7'])
    assert cache.get_size() == 2

    cache.remove_all()
    assert cache.get_size() == 0


def test_cache_get(client):
    my_cache = client.get_or_create_cache('my_cache')
    assert my_cache.settings[PROP_NAME] == 'my_cache'
    my_cache.destroy()

    error = None

    my_cache = client.get_cache('my_cache')
    try:
        _ = my_cache.settings[PROP_NAME]
    except CacheError as e:
        error = e

    assert type(error) is CacheError


def test_cache_config(client):
    cache_config = {
        PROP_NAME: 'my_oop_cache',
        PROP_CACHE_KEY_CONFIGURATION: [
            {
                'type_name': 'blah',
                'affinity_key_field_name': 'abc1234',
            },
        ],
    }
    client.create_cache(cache_config)

    cache = client.get_or_create_cache('my_oop_cache')
    assert cache.name == cache_config[PROP_NAME]
    assert (
        cache.settings[PROP_CACHE_KEY_CONFIGURATION]
        == cache_config[PROP_CACHE_KEY_CONFIGURATION]
    )

    cache.destroy()


def test_cache_get_put(client):
    cache = client.get_or_create_cache('my_oop_cache')
    cache.put('my_key', 42)
    result = cache.get('my_key')
    assert result, 42
    cache.destroy()


def test_cache_binary_get_put(client):

    class TestBinaryType(
        metaclass=GenericObjectMeta,
        schema=OrderedDict([
            ('test_bool', BoolObject),
            ('test_str', String),
            ('test_int', IntObject),
            ('test_decimal', DecimalObject),
        ]),
    ):
        pass

    cache = client.create_cache('my_oop_cache')

    my_value = TestBinaryType(
        test_bool=True,
        test_str='This is a test',
        test_int=42,
        test_decimal=Decimal('34.56'),
    )
    cache.put('my_key', my_value)

    value = cache.get('my_key')
    assert value.test_bool is True
    assert value.test_str == 'This is a test'
    assert value.test_int == 42
    assert value.test_decimal == Decimal('34.56')

    cache.destroy()


def test_get_binary_type(client):
    client.put_binary_type(
        'TestBinaryType',
        schema=OrderedDict([
            ('TEST_BOOL', BoolObject),
            ('TEST_STR', String),
            ('TEST_INT', IntObject),
        ])
    )
    client.put_binary_type(
        'TestBinaryType',
        schema=OrderedDict([
            ('TEST_BOOL', BoolObject),
            ('TEST_STR', String),
            ('TEST_INT', IntObject),
            ('TEST_FLOAT', FloatObject),
        ])
    )
    client.put_binary_type(
        'TestBinaryType',
        schema=OrderedDict([
            ('TEST_BOOL', BoolObject),
            ('TEST_STR', String),
            ('TEST_INT', IntObject),
            ('TEST_DECIMAL', DecimalObject),
        ])
    )

    binary_type_info = client.get_binary_type('TestBinaryType')
    assert len(binary_type_info['schemas']) == 3

    binary_type_info = client.get_binary_type('NonExistentType')
    assert binary_type_info['type_exists'] is False
    assert len(binary_type_info) == 1


@pytest.mark.parametrize('page_size', range(1, 17, 5))
def test_cache_scan(request, client, page_size):
    test_data = {
        1: 'This is a test',
        2: 'One more test',
        3: 'Foo',
        4: 'Buzz',
        5: 'Bar',
        6: 'Lorem ipsum',
        7: 'dolor sit amet',
        8: 'consectetur adipiscing elit',
        9: 'Nullam aliquet',
        10: 'nisl at ante',
        11: 'suscipit',
        12: 'ut cursus',
        13: 'metus interdum',
        14: 'Nulla tincidunt',
        15: 'sollicitudin iaculis',
    }

    cache = client.get_or_create_cache(request.node.name)
    cache.put_all(test_data)

    gen = cache.scan(page_size=page_size)
    received_data = []
    for k, v in gen:
        assert k in test_data.keys()
        assert v in test_data.values()
        received_data.append((k, v))
    assert len(received_data) == len(test_data)

    cache.destroy()


def test_get_and_put_if_absent(client):
    cache = client.get_or_create_cache('my_oop_cache')

    value = cache.get_and_put_if_absent('my_key', 42)
    assert value is None
    cache.put('my_key', 43)
    value = cache.get_and_put_if_absent('my_key', 42)
    assert value is 43


def test_cache_get_when_cache_does_not_exist(client):
    cache = client.get_cache('missing-cache')
    with pytest.raises(CacheError) as e_info:
        cache.put(1, 1)
    assert str(e_info.value) == "Cache does not exist [cacheId= 1665146971]"


def test_cache_create_with_none_name(client):
    with pytest.raises(ParameterError) as e_info:
        client.create_cache(None)
    assert str(e_info.value) == "You should supply at least cache name"


