#
# Copyright (c) Daniel Sheffield 2023
#
# All rights reserved
#
# THIS SOFTWARE IS PROVIDED AS IS WITHOUT WARRANTY
from pytest import mark, fixture
from app.data.QueryManager import (
    cursor_as_dict,
    record_matches,
    get_insert_product_statement,
)

@fixture
def cur():
    class MockDescription:
        def __init__(self, name) -> None:
            self.name = name

    class MockCursor:
        description = [
            MockDescription('col1'),
            MockDescription('col2'),
            MockDescription('col3')
        ]
        def fetchall(self):
            return [
                ['val00', None, 'val02'],
                ['val10', 'val11', 'val12'],
                ['val20', 'val21', None],
            ]
    return MockCursor()

def test_cursor_as_dict(cur):
    assert list(cursor_as_dict(cur)) == [{
        'col1': 'val00',
        'col2': None,
        'col3': 'val02',
    },{
        'col1': 'val10',
        'col2': 'val11',
        'col3': 'val12',
    },{
        'col1': 'val20',
        'col2': 'val21',
        'col3': None,
    }]

@mark.parametrize('record, kwargs, strict, expected', [
    ({'key1': 'abc', 'key2': 'def'}, {'key1': 'a'}, None, True),
    ({'key1': 'abc', 'key2': 'def'}, {'key1': 'b'}, None, True),
    ({'key1': 'abc', 'key2': 'def'}, {'key1': 'abc'}, ['KEY1'], True),
    ({'key1': 'abc', 'key2': 'def'}, {'key1': 'a', 'key2': 'b'}, None, False),
    ({'key1': 'abc', 'key2': 'def'}, {'key1': 'b', 'key2': 'c'}, None, False),
    ({'key1': 'abc', 'key2': 'def'}, {'key1': 'abc', 'key2': 'e'}, ['KEY1'], True),
    ({'key1': 'abc', 'key2': 'def'}, {'key1': 'abc', 'key2': 'e'}, ['KEY1', 'KEY2'], False),
    ({'key1': 'abc', 'key2': 'def'}, {'key1': ''}, None, True),
    ({'key1': 'abc', 'key2': 'def'}, {'key1': ''}, ['KEY1'], True),
])
def test_record_matches(record, strict, kwargs, expected):
    assert record_matches(record, strict, **kwargs) == expected


@mark.parametrize('product, category, group, unit, expected', [
    ('apple', 'fruit', 'produce', 'kg',
     'CALL insert_product($prod$apple$prod$, $category$fruit$category$, $group$produce$group$, $unit$kg$unit$)'),
    ('apple', 'fruit', 'produce', '',
     'CALL insert_product($prod$apple$prod$, $category$fruit$category$, $group$produce$group$)'),
    ('apple', 'fruit', 'produce', None,
     'CALL insert_product($prod$apple$prod$, $category$fruit$category$, $group$produce$group$)'),
])
def test_get_insert_product_statement(product, category, group, unit, expected):
    assert get_insert_product_statement(product, category, group, unit) == expected