# coding: utf-8
from .autopath import do_autopath
do_autopath()

from py.test import raises

from tiramisu.option import IntOption, UnicodeOption, OptionDescription
from tiramisu.config import Config
from tiramisu.error import PropertiesOptionError


def make_description():
    u1 = IntOption('u1', '', properties=('frozen', 'mandatory', 'disabled', ))
    u2 = IntOption('u2', '', properties=('frozen', 'mandatory', 'disabled', ))
    return OptionDescription('od1', '', [u1, u2])


def test_permissive():
    descr = make_description()
    config = Config(descr)
    setting = config.cfgimpl_get_settings()
    config.read_write()
    props = []
    try:
        config.u1
    except PropertiesOptionError as err:
        props = err.proptype
    assert props == ['disabled']
    setting.setpermissive(('disabled',))
    props = []
    try:
        config.u1
    except PropertiesOptionError as err:
        props = err.proptype
    assert props == ['disabled']
    setting.append('permissive')
    config.u1
    setting.remove('permissive')
    props = []
    try:
        config.u1
    except PropertiesOptionError as err:
        props = err.proptype
    assert props == ['disabled']


def test_permissive_mandatory():
    descr = make_description()
    config = Config(descr)
    setting = config.cfgimpl_get_settings()
    config.read_only()
    props = []
    try:
        config.u1
    except PropertiesOptionError as err:
        props = err.proptype
    assert set(props) == set(['disabled', 'mandatory'])
    setting.setpermissive(('mandatory', 'disabled',))
    setting.append('permissive')
    config.u1
    setting.remove('permissive')
    try:
        config.u1
    except PropertiesOptionError as err:
        props = err.proptype
    assert set(props) == set(['disabled', 'mandatory'])


def test_permissive_frozen():
    descr = make_description()
    config = Config(descr)
    setting = config.cfgimpl_get_settings()
    config.read_write()
    setting.setpermissive(('frozen', 'disabled',))
    try:
        config.u1 = 1
    except PropertiesOptionError as err:
        props = err.proptype
    assert set(props) == set(['frozen', 'disabled'])
    setting.append('permissive')
    config.u1 = 1
    assert config.u1 == 1
    setting.remove('permissive')
    try:
        config.u1 = 1
    except PropertiesOptionError as err:
        props = err.proptype
    assert set(props) == set(['frozen', 'disabled'])


def test_invalid_permissive():
    descr = make_description()
    config = Config(descr)
    setting = config.cfgimpl_get_settings()
    config.read_write()
    raises(TypeError, "setting.setpermissive(['frozen', 'disabled',])")


def test_permissive_option():
    descr = make_description()
    u1 = descr.u1
    config = Config(descr)
    setting = config.cfgimpl_get_settings()
    config.read_write()

    props = []
    try:
        config.u1
    except PropertiesOptionError as err:
        props = err.proptype
    assert props == ['disabled']
    props = []
    try:
        config.u2
    except PropertiesOptionError as err:
        props = err.proptype
    assert props == ['disabled']

    setting.setpermissive(('disabled',), u1)
    props = []
    try:
        config.u1
    except PropertiesOptionError as err:
        props = err.proptype
    assert props == []
    props = []
    try:
        config.u2
    except PropertiesOptionError as err:
        props = err.proptype
    assert props == ['disabled']

    setting.append('permissive')
    config.u1
    props = []
    try:
        config.u2
    except PropertiesOptionError as err:
        props = err.proptype
    assert props == ['disabled']

    setting.remove('permissive')
    props = []
    try:
        config.u1
    except PropertiesOptionError as err:
        props = err.proptype
    assert props == []
    props = []
    try:
        config.u2
    except PropertiesOptionError as err:
        props = err.proptype
    assert props == ['disabled']


def test_permissive_option_cache():
    descr = make_description()
    u1 = descr.u1
    config = Config(descr)
    setting = config.cfgimpl_get_settings()
    config.read_write()
    setting.remove('expire')

    props = []
    try:
        config.u1
    except PropertiesOptionError as err:
        props = err.proptype
    assert props == ['disabled']
    props = []
    try:
        config.u2
    except PropertiesOptionError as err:
        props = err.proptype
    assert props == ['disabled']

    setting.setpermissive(('disabled',), u1)
    props = []
    try:
        config.u1
    except PropertiesOptionError as err:
        props = err.proptype
    assert props == []
    props = []
    try:
        config.u2
    except PropertiesOptionError as err:
        props = err.proptype
    assert props == ['disabled']

    setting.append('permissive')
    config.u1
    props = []
    try:
        config.u2
    except PropertiesOptionError as err:
        props = err.proptype
    assert props == ['disabled']

    setting.remove('permissive')
    props = []
    try:
        config.u1
    except PropertiesOptionError as err:
        props = err.proptype
    assert props == []
    props = []
    try:
        config.u2
    except PropertiesOptionError as err:
        props = err.proptype
    assert props == ['disabled']


def test_permissive_option_mandatory():
    descr = make_description()
    u1 = descr.u1
    config = Config(descr)
    setting = config.cfgimpl_get_settings()
    config.read_only()
    props = []
    try:
        config.u1
    except PropertiesOptionError as err:
        props = err.proptype
    assert set(props) == set(['disabled', 'mandatory'])
    setting.setpermissive(('mandatory', 'disabled',), u1)
    setting.append('permissive')
    config.u1
    setting.remove('permissive')
    try:
        config.u1
    except PropertiesOptionError as err:
        props = err.proptype
    assert set(props) == set(['disabled', 'mandatory'])


def test_permissive_option_frozen():
    descr = make_description()
    config = Config(descr)
    u1 = descr.u1
    setting = config.cfgimpl_get_settings()
    config.read_write()
    setting.setpermissive(('frozen', 'disabled'), u1)
    config.u1 = 1
    assert config.u1 == 1
    setting.append('permissive')
    assert config.u1 == 1
    setting.remove('permissive')
    assert config.u1 == 1


def test_invalid_option_permissive():
    descr = make_description()
    u1 = descr.u1
    config = Config(descr)
    setting = config.cfgimpl_get_settings()
    config.read_write()
    raises(TypeError, "setting.setpermissive(['frozen', 'disabled',], u1)")


def test_remove_option_permissive():
    var1 = UnicodeOption('var1', '', u'value', properties=('hidden',))
    od1 = OptionDescription('od1', '', [var1])
    rootod = OptionDescription('rootod', '', [od1])
    config = Config(rootod)
    config.read_write()
    raises(PropertiesOptionError, "config.od1.var1")
    config.cfgimpl_get_settings().setpermissive(('hidden',), var1)
    assert config.od1.var1 == u'value'
    config.cfgimpl_get_settings().setpermissive(tuple(), var1)
    raises(PropertiesOptionError, "config.od1.var1")