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

from zirkon import Config
from zirkon.toolbox.serializer import (
    Serializer,
    ZirkonSerializer,
    DotsSerializer,
    PathSerializer,
)

import pytest

@pytest.fixture(params=tuple(Serializer.get_class_tags()))
def fmt(request):
    return request.param


@pytest.mark.regression('8973ae1af7a0b9baddaa811f667af1c45bc58b40')
def test_serializer_empty(fmt):
    # test to fix toml library bug (toml->pytoml)
    serializer = Serializer.get_class(fmt)(scope=Config.scope())
    dct = {
        'a': {},
        'b': {
            'b0': 10,
            'b1': {},
            'b2': {'b2_0': 10},
        }
    }
    s = serializer.to_string(dct)
    dct1 = serializer.from_string(s)
    print(dct)
    print(dct1)
    assert dct == dct1


@pytest.fixture(params=[
    ZirkonSerializer,
    DotsSerializer,
    PathSerializer,
])
def cont_serializer(request):
    return request.param(scope=Config.scope())

def get_key(key, serializer):
    if isinstance(serializer, PathSerializer):
        return '/' + key
    else:
        return key

def test_explicit_continuation_line(cont_serializer):
    source = """\
{key} = [10, \\
     20, \\
     30]""".format(key=get_key('a', cont_serializer))
    print(repr(source))
    x = cont_serializer.from_string(source)
    assert x['a'] == [10, 20, 30]

def test_explicit_continuation_last_line(cont_serializer):
    source = "{key} = 10 \\".format(key=get_key('a', cont_serializer))
    with pytest.raises(SyntaxError) as exc_info:
        x = cont_serializer.from_string(source)
    assert str(exc_info.value) == "incomplete last line"

@pytest.fixture(params=[
    ("{key} =\n  10\n", {'a': 10}),
    ("{key} = [1, 2\n,3,4,\n5\n]\n", {'a': [1, 2, 3, 4, 5]}),
    ("{key} = (1, 2\n,3,4,\n5\n)\n", {'a': (1, 2, 3, 4, 5)}),
    ("{key} = (1, 2\n,3,4 #, 19\n,5\n)\n", {'a': (1, 2, 3, 4, 5)}),
    ('''{key} = """abc
def"""''', {'a': "abc\ndef"}),
    ("""{key} = '''abc
def'''""", {'a': "abc\ndef"}),
])
def impl_cont_source(request):
    return request.param

def test_implicit_continuation_line(cont_serializer, impl_cont_source):
    source, result = impl_cont_source
    source = source.format(key=get_key('a', cont_serializer))
    print(cont_serializer)
    print(repr(source))
    x = cont_serializer.from_string(source)
    assert x == result

@pytest.fixture(params=[
    ("{key} = \n[1, 2,\n3a,4]\n", 3, "[1, 2,\n3a,4]"),
    ("{key} = \\\n[1, 2,\\\n3a,4]\n", 3, "[1, 2,3a,4]"),
])
def err_cont_source(request):
    return request.param

def test_continuation_line_error(cont_serializer, err_cont_source):
    source, line_number, srcval = err_cont_source
    source = source.format(key=get_key('a', cont_serializer))
    with pytest.raises(ValueError) as exc_info:
        cont_serializer.from_string(source)
    msg = "line {}@<string>: cannot decode value {!r}" .format(line_number, srcval)
    # print(exc_info.value)
    # print(msg)
    assert str(exc_info.value) == msg
