from .autopath import do_autopath
do_autopath()

import warnings, sys
from py.test import raises

from tiramisu import Config
from tiramisu.option import DomainnameOption, EmailOption, URLOption, OptionDescription
from tiramisu.error import ValueWarning
from tiramisu.i18n import _
from tiramisu.storage import list_sessions


def teardown_function(function):
    assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__)


def test_domainname():
    d = DomainnameOption('d', '')
    f = DomainnameOption('f', '', allow_without_dot=True)
    g = DomainnameOption('g', '', allow_ip=True)
    od = OptionDescription('a', '', [d, f, g])
    cfg = Config(od)
    cfg.property.read_write()
    cfg.option('d').value.set('toto.com')
    raises(ValueError, "cfg.option('d').value.set('toto')")
    cfg.option('d').value.set('toto3.com')
    raises(ValueError, "cfg.option('d').value.set('toto_super.com')")
    cfg.option('d').value.set('toto-.com')
    raises(ValueError, "cfg.option('d').value.set('toto..com')")
    #
    cfg.option('f').value.set('toto.com')
    cfg.option('f').value.set('toto')
    cfg.option('f').value.set('domainnametoolongthathavemorethanmaximumsizeforatruedomainnamea')
    raises(ValueError, "cfg.option('f').value.set('domainnametoolongthathavemorethanmaximumsizeforatruedomainnamean')")
    cfg.option('f').value.set('domainnametoolongthathavemorethanmaximumsizeforatruedomainnamea.nd')
    cfg.option('f').value.set('domainnametoolongthathavemorethanmaximumsizeforatruedomainnamea.nditsnoteasytogeneratesolongdomainnamewithoutrepeatdomainnameto.olongthathavemorethanmaximumsizeforatruedomainnameanditsnoteas.ytogeneratesolongdomainnamewithoutrepeatbutimnotabletodoitnowie')
    raises(ValueError, "cfg.option('d').value.set('domainnametoolongthathavemorethanmaximumsizeforatruedomainnamea.nditsnoteasytogeneratesolongdomainnamewithoutrepeatdomainnameto.olongthathavemorethanmaximumsizeforatruedomainnameanditsnoteas.ytogeneratesolongdomainnamewithoutrepeatbutimnotabletodoitnowien')")
    cfg.option('f').value.set('d')
    cfg.option('f').value.set('d.t')
    #
    raises(ValueError, "cfg.option('f').value.set('192.168.1.1')")
    cfg.option('g').value.set('toto.com')
    cfg.option('g').value.set('192.168.1.0')
    cfg.option('g').value.set('192.168.1.29')


def test_domainname_upper():
    d = DomainnameOption('d', '')
    od = OptionDescription('a', '', [d])
    cfg = Config(od)
    cfg.property.read_write()
    cfg.option('d').value.set('toto.com')
    msg = _('some characters are uppercase')
    has_error = False
    try:
        cfg.option('d').value.set('TOTO.COM')
    except ValueError as err:
        assert msg in str(err)
        has_error = True
    assert has_error is True
    has_error = False
    try:
        cfg.option('d').value.set('toTo.com')
    except ValueError as err:
        assert msg in str(err)
        has_error = True
    assert has_error is True


def test_domainname_warning():
    d = DomainnameOption('d', '', warnings_only=True)
    f = DomainnameOption('f', '', allow_without_dot=True, warnings_only=True)
    g = DomainnameOption('g', '', allow_ip=True, warnings_only=True)
    od = OptionDescription('a', '', [d, f, g])
    warnings.simplefilter("always", ValueWarning)
    cfg = Config(od)
    cfg.property.read_write()
    cfg.option('d').value.set('toto.com')
    raises(ValueError, "cfg.option('d').value.set('toto')")
    cfg.option('d').value.set('toto3.com')
    with warnings.catch_warnings(record=True) as w:
        cfg.option('d').value.set('toto_super.com')
    assert len(w) == 1
    with warnings.catch_warnings(record=True) as w:
        cfg.option('d').value.set('toto-.com')
    assert len(w) == 0
    raises(ValueError, "cfg.option('d').value.set('toto..com')")
    #
    cfg.option('f').value.set('toto.com')
    cfg.option('f').value.set('toto')
    cfg.option('f').value.set('domainnametoolongthathavemorethanmaximumsizeforatruedomainnamea')
    raises(ValueError, "cfg.option('f').value.set('domainnametoolongthathavemorethanmaximumsizeforatruedomainnamean')")
    cfg.option('f').value.set('domainnametoolongthathavemorethanmaximumsizeforatruedomainnamea.nd')
    cfg.option('f').value.set('domainnametoolongthathavemorethanmaximumsizeforatruedomainnamea.nditsnoteasytogeneratesolongdomainnamewithoutrepeatdomainnameto.olongthathavemorethanmaximumsizeforatruedomainnameanditsnoteas.ytogeneratesolongdomainnamewithoutrepeatbutimnotabletodoitnowie')
    raises(ValueError, "cfg.option('f').value.set('domainnametoolongthathavemorethanmaximumsizeforatruedomainname.nditsnoteasytogeneratesolongdomainnamewithoutrepeatdomainnamet.olongthathavemorethanmaximumsizeforatruedomainnameanditsnotea.ytogeneratesolongdomainnamewithoutrepeatbutimnotabletodoitnowie.xxxx')")
    cfg.option('f').value.set('d')
    cfg.option('f').value.set('d.t')
    #
    raises(ValueError, "cfg.option('f').value.set('192.168.1.1')")
    cfg.option('g').value.set('toto.com')
    cfg.option('g').value.set('192.168.1.0')
    cfg.option('g').value.set('192.168.1.29')


def test_special_domain_name():
    """domain name option that starts with a number or not
    """
    d = DomainnameOption('d', '')
    e = DomainnameOption('e', '', type_='netbios')
    od = OptionDescription('a', '', [d, e])
    cfg = Config(od)
    cfg.property.read_write()
    cfg.option('d').value.set('1toto.com')
    cfg.option('d').value.set('123toto.com')
    cfg.option('e').value.set('toto')
    cfg.option('e').value.set('1toto')


def test_domainname_netbios():
    d = DomainnameOption('d', '', type_='netbios')
    e = DomainnameOption('e', '', "toto", type_='netbios')
    od = OptionDescription('a', '', [d, e])
    cfg = Config(od)
    cfg.property.read_write()
    raises(ValueError, "cfg.option('d').value.set('toto.com')")
    cfg.option('d').value.set('toto')
    raises(ValueError, "cfg.option('d').value.set('domainnametoolong')")


def test_domainname_hostname():
    d = DomainnameOption('d', '', type_='hostname')
    e = DomainnameOption('e', '', "toto", type_='hostname')
    od = OptionDescription('a', '', [d, e])
    cfg = Config(od)
    cfg.property.read_write()
    raises(ValueError, "cfg.option('d').value.set('toto.com')")
    cfg.option('d').value.set('toto')
    cfg.option('d').value.set('domainnametoolong')


def test_email():
    e = EmailOption('e', '')
    od = OptionDescription('a', '', [e])
    cfg = Config(od)
    cfg.property.read_write()
    cfg.option('e').value.set('foo-bar.baz@example.com')
    cfg.option('e').value.set('root@foo.com')
    cfg.option('e').value.set('root@domain')
    raises(ValueError, "cfg.option('e').value.set(1)")
    raises(ValueError, "cfg.option('e').value.set('root')")
    raises(ValueError, "cfg.option('e').value.set('root[]@domain')")


def test_url():
    u = URLOption('u', '')
    od = OptionDescription('a', '', [u])
    cfg = Config(od)
    cfg.property.read_write()
    cfg.option('u').value.set('http://foo.com')
    cfg.option('u').value.set('https://foo.com')
    cfg.option('u').value.set('https://foo.com/')
    raises(ValueError, "cfg.option('u').value.set(1)")
    raises(ValueError, "cfg.option('u').value.set('ftp://foo.com')")
    raises(ValueError, "cfg.option('u').value.set('foo.com')")
    raises(ValueError, "cfg.option('u').value.set(':/foo.com')")
    raises(ValueError, "cfg.option('u').value.set('foo.com/http://')")
    cfg.option('u').value.set('https://foo.com/index.html')
    cfg.option('u').value.set('https://foo.com/index.html?var=value&var2=val2')
    raises(ValueError, "cfg.option('u').value.set('https://foo.com/index\\n.html')")
    cfg.option('u').value.set('https://foo.com:8443')
    cfg.option('u').value.set('https://foo.com:8443/')
    cfg.option('u').value.set('https://foo.com:8443/index.html')
    raises(ValueError, "cfg.option('u').value.set('https://foo.com:84438989')")
    cfg.option('u').value.set('https://foo.com:8443/INDEX')
    raises(ValueError, "cfg.option('u').value.set('https://FOO.COM:8443')")