import py
import pytest
from py._iniconfig import IniConfig, ParseError, __all__ as ALL
from py._iniconfig import iscommentline
from textwrap import dedent

def pytest_generate_tests(metafunc):
    if 'input' in metafunc.funcargnames:
        for name, (input, expected) in check_tokens.items():
            metafunc.addcall(id=name, funcargs={
                'input': input,
                'expected': expected,
            })
    elif hasattr(metafunc.function, 'multi'):
        kwargs = metafunc.function.multi.kwargs
        names, values = zip(*kwargs.items())
        values = cartesian_product(*values)
        for p in values:
            metafunc.addcall(funcargs=dict(zip(names, p)))

def cartesian_product(L,*lists):
    # copied from http://bit.ly/cyIXjn
    if not lists:
        for x in L:
            yield (x,)
    else:
        for x in L:
            for y in cartesian_product(lists[0],*lists[1:]):
                yield (x,)+y

check_tokens = {
    'section': (
        '[section]',
        [(0, 'section', None, None)]
    ),
    'value': (
        'value = 1',
        [(0, None, 'value', '1')]
    ),
    'value in section': (
        '[section]\nvalue=1',
        [(0, 'section', None, None), (1, 'section', 'value', '1')]
    ),
    'value with continuation': (
        'names =\n Alice\n Bob',
        [(0, None, 'names', 'Alice\nBob')]
    ),
    'value with aligned continuation': (
        'names = Alice\n'
        '        Bob',
        [(0, None, 'names', 'Alice\nBob')]
    ),
    'blank line':(
        '[section]\n\nvalue=1',
        [(0, 'section', None, None), (2, 'section', 'value', '1')]
    ),
    'comment': (
        '# comment',
        []
    ),
    'comment on value': (
        'value = 1',
        [(0, None, 'value', '1')]
    ),

    'comment on section': (
        '[section] #comment',
        [(0, 'section', None, None)]
    ),
    'comment2': (
        '; comment',
        []
    ),

    'comment2 on section': (
        '[section] ;comment',
        [(0, 'section', None, None)]
    ),
    'pseudo section syntax in value': (
        'name = value []',
        [(0, None, 'name', 'value []')]
    ),
    'assignment in value': (
        'value = x = 3',
        [(0, None, 'value', 'x = 3')]
    ),
    'use of colon for name-values': (
        'name: y',
        [(0, None, 'name', 'y')]
    ),
    'use of colon without space': (
        'value:y=5',
        [(0, None, 'value', 'y=5')]
    ),
    'equality gets precedence': (
        'value=xyz:5',
        [(0, None, 'value', 'xyz:5')]
    ),

}

def parse(input):
    # only for testing purposes - _parse() does not use state except path
    ini = object.__new__(IniConfig)
    ini.path = "sample"
    return ini._parse(input.splitlines(True))

def parse_a_error(input):
    return py.test.raises(ParseError, parse, input)

def test_tokenize(input, expected):
    parsed = parse(input)
    assert parsed == expected

def test_parse_empty():
    parsed = parse("")
    assert not parsed
    ini = IniConfig("sample", "")
    assert not ini.sections

def test_ParseError():
    e = ParseError("filename", 0, "hello")
    assert str(e) == "filename:1: hello"

def test_continuation_needs_perceeding_token():
    excinfo = parse_a_error(' Foo')
    assert excinfo.value.lineno == 0

def test_continuation_cant_be_after_section():
    excinfo = parse_a_error('[section]\n Foo')
    assert excinfo.value.lineno == 1

def test_section_cant_be_empty():
    excinfo = parse_a_error('[]')

@py.test.mark.multi(line=[
    '!!',
    ])
def test_error_on_weird_lines(line):
    parse_a_error(line)

def test_iniconfig_from_file(tmpdir):
    path = tmpdir/'test.txt'
    path.write('[metadata]\nname=1')

    config = IniConfig(path=path)
    assert list(config.sections) == ['metadata']
    config = IniConfig(path, "[diff]")
    assert list(config.sections) == ['diff']
    py.test.raises(TypeError, "IniConfig(data=path.read())")

def test_iniconfig_section_first(tmpdir):
    excinfo = py.test.raises(ParseError, """
        IniConfig("x", data='name=1')
    """)
    assert excinfo.value.msg == "no section header defined"

def test_iniconig_section_duplicate_fails():
    excinfo = py.test.raises(ParseError, r"""
        IniConfig("x", data='[section]\n[section]')
    """)
    assert 'duplicate section' in str(excinfo.value)

def test_iniconfig_duplicate_key_fails():
    excinfo = py.test.raises(ParseError, r"""
        IniConfig("x", data='[section]\nname = Alice\nname = bob')
    """)

    assert 'duplicate name' in str(excinfo.value)

def test_iniconfig_lineof():
    config = IniConfig("x.ini", data=
        '[section]\n'
        'value = 1\n'
        '[section2]\n'
        '# comment\n'
        'value =2'
    )

    assert config.lineof('missing') is None
    assert config.lineof('section') == 1
    assert config.lineof('section2') == 3
    assert config.lineof('section', 'value') == 2
    assert config.lineof('section2','value') == 5

    assert config['section'].lineof('value') == 2
    assert config['section2'].lineof('value') == 5

def test_iniconfig_get_convert():
    config= IniConfig("x", data='[section]\nint = 1\nfloat = 1.1')
    assert config.get('section', 'int') == '1'
    assert config.get('section', 'int', convert=int) == 1

def test_iniconfig_get_missing():
    config= IniConfig("x", data='[section]\nint = 1\nfloat = 1.1')
    assert config.get('section', 'missing', default=1) == 1
    assert config.get('section', 'missing') is None

def test_section_get():
    config = IniConfig("x", data='[section]\nvalue=1')
    section = config['section']
    assert section.get('value', convert=int) == 1
    assert section.get('value', 1) == "1"
    assert section.get('missing', 2) == 2

def test_missing_section():
    config = IniConfig("x", data='[section]\nvalue=1')
    py.test.raises(KeyError,'config["other"]')

def test_section_getitem():
    config = IniConfig("x", data='[section]\nvalue=1')
    assert config['section']['value'] == '1'
    assert config['section']['value'] == '1'

def test_section_iter():
    config = IniConfig("x", data='[section]\nvalue=1')
    names = list(config['section'])
    assert names == ['value']
    items = list(config['section'].items())
    assert items==[('value', '1')]

def test_config_iter():
    config = IniConfig("x.ini", data=dedent('''
          [section1]
          value=1
          [section2]
          value=2
    '''))
    l = list(config)
    assert len(l) == 2
    assert l[0].name == 'section1'
    assert l[0]['value'] == '1'
    assert l[1].name == 'section2'
    assert l[1]['value'] == '2'

def test_config_contains():
    config = IniConfig("x.ini", data=dedent('''
          [section1]
          value=1
          [section2]
          value=2
    '''))
    assert 'xyz' not in config
    assert 'section1' in config
    assert 'section2' in config

def test_iter_file_order():
    config = IniConfig("x.ini", data="""
[section2] #cpython dict ordered before section
value = 1
value2 = 2 # dict ordered before value
[section]
a = 1
b = 2
""")
    l = list(config)
    secnames = [x.name for x in l]
    assert secnames == ['section2', 'section']
    assert list(config['section2']) == ['value', 'value2']
    assert list(config['section']) == ['a', 'b']

def test_example_pypirc():
    config = IniConfig("pypirc", data=dedent('''
        [distutils]
        index-servers =
            pypi
            other

        [pypi]
        repository: <repository-url>
        username: <username>
        password: <password>

        [other]
        repository: http://example.com/pypi
        username: <username>
        password: <password>
    '''))
    distutils, pypi, other = list(config)
    assert distutils["index-servers"] == "pypi\nother"
    assert pypi['repository'] == '<repository-url>'
    assert pypi['username'] == '<username>'
    assert pypi['password'] == '<password>'
    assert ['repository', 'username', 'password'] == list(other)


def test_api_import():
    assert ALL == ['IniConfig', 'ParseError']

@pytest.mark.parametrize("line", [
    "#qwe",
    "  #qwe",
    ";qwe",
    " ;qwe",
])
def test_iscommentline_true(line):
    assert iscommentline(line)


