"""test consistencies about multi and submulti"""
from py.test import raises
from .autopath import do_autopath
do_autopath()
from tiramisu.setting import groups
from tiramisu import Config, StrOption, IntOption, OptionDescription, MasterSlaves, getapi, \
                     submulti, undefined
from tiramisu.error import PropertiesOptionError


def return_val(val=None):
    if val is None:
        return 'val'
    else:
        return val


def return_list(value=None):
    return ['val', 'val']


def return_list2(value=None):
    return [['val', 'val']]


def test_multi_unique():
    int_ = IntOption('int', '', multi=True, unique=True)
    od_ = OptionDescription('od', '', [int_])
    cfg = Config(od_)
    api = getapi(cfg)
    assert api.option('int').value.get() == []
    value = [0]
    api.option('int').value.set(value)
    assert api.option('int').value.get() == value
    value.append(1)
    assert api.option('int').value.get() == [0]
    raises(ValueError, "api.option('int').value.set([0, 0])")
    raises(ValueError, "api.option('int').value.set([1, 0, 2, 3, 4, 5, 6, 0, 7])")


def test_multi_none():
    str_ = StrOption('str', '', multi=True)
    od_ = OptionDescription('od', '', [str_])
    cfg = Config(od_)
    cfg.read_only()
    api = getapi(cfg)
    assert api.option('str').value.get() == []
    cfg.read_write()
    api.option('str').value.set([None])
    assert api.option('str').value.get() == [None]
    cfg.read_only()
    raises(PropertiesOptionError, "api.option('str').value.get()")
    cfg.read_write()
    api.option('str').value.set([''])
    assert api.option('str').value.get() == ['']
    cfg.read_only()
    raises(PropertiesOptionError, "api.option('str').value.get()")


# ______________ submulti ______________

def test_append_submulti():
    multi = StrOption('multi', '', multi=submulti)
    multi2 = StrOption('multi2', '', default_multi=['yes'], multi=submulti)
    multi3 = StrOption('multi3', '', default=[['yes']], multi=submulti)
    od_ = OptionDescription('od', '', [multi, multi2, multi3])
    cfg = Config(od_)
    api = getapi(cfg)
    #FIXME
    owner = cfg.cfgimpl_get_settings().getowner()
    assert api.option('multi').value.get() == []
    assert api.option('multi').value.get() == []
    assert api.option('multi').owner.isdefault()
    api.option('multi').value.set([undefined])
    assert api.option('multi').owner.get() == owner
    value = api.option('multi').value.get()
    assert value == [[]]
    value.append(['no'])
    assert api.option('multi').value.get() == [[]]
    api.option('multi').value.set(value)
    assert api.option('multi').value.get() == [[], ['no']]
    #
    assert api.option('multi2').value.get() == []
    assert api.option('multi2').owner.isdefault()
    api.option('multi2').value.set([undefined])
    assert api.option('multi2').owner.get() == owner
    assert api.option('multi2').value.get() == [['yes']]
    api.option('multi2').value.set([['yes'], ['no']])
    assert api.option('multi2').value.get() == [['yes'], ['no']]
    #
    assert api.option('multi3').value.get() == [['yes']]
    assert api.option('multi3').owner.isdefault()
    api.option('multi3').value.set([['yes'], undefined])
    assert api.option('multi3').owner.get() == owner
    assert api.option('multi3').value.get() == [['yes'], []]
    api.option('multi3').value.set([['yes'], [], ['no']])
    assert api.option('multi3').value.get() == [['yes'], [], ['no']]


def test_append_unvalide_submulti():
    multi = StrOption('multi', '', multi=submulti)
    multi2 = StrOption('multi2', '', default_multi=['yes'], multi=submulti)
    multi3 = StrOption('multi3', '', default=[['yes']], multi=submulti)
    od_ = OptionDescription('od', '', [multi, multi2, multi3])
    cfg = Config(od_)
    api = getapi(cfg)
    assert api.option('multi').value.get() == []
    assert api.option('multi').owner.isdefault()
    raises(ValueError, "api.option('multi').value.set([1])")
    assert api.option('multi').value.get() == []
    assert api.option('multi').owner.isdefault()
    #
    assert api.option('multi2').value.get() == []
    raises(ValueError, "api.option('multi2').value.set('no')")
    assert api.option('multi2').owner.isdefault()
    assert api.option('multi2').value.get() == []
    #
    assert api.option('multi3').value.get() == [['yes']]
    assert api.option('multi3').owner.isdefault()


def test_submulti_unique():
    int_ = IntOption('int', '', multi=submulti, unique=True)
    od_ = OptionDescription('od', '', [int_])
    cfg = Config(od_)
    api = getapi(cfg)
    assert api.option('int').value.get() == []
    api.option('int').value.set([[0]])
    assert api.option('int').value.get() == [[0]]
    raises(ValueError, "api.option('int').value.set([[0, 0]])")
    api.option('int').value.set([[0], [0]])
    raises(ValueError, "api.option('int').value.set([[0], [1, 0, 2, 3, 4, 5, 6, 0, 7]])")


def test_callback_reset():
    multi = StrOption('multi', '', multi=submulti, callback=return_val)
    od_ = OptionDescription('od', '', [multi])
    cfg = Config(od_)
    cfg.read_write()
    api = getapi(cfg)
    #FIXME
    owner = cfg.cfgimpl_get_settings().getowner()
    assert api.option('multi').value.get() == [['val']]
    assert api.option('multi').owner.isdefault()
    api.option('multi').value.set([['val'], undefined])
    assert api.option('multi').owner.get() == owner
    assert api.option('multi').value.get() == [['val'], ['val']]
    api.option('multi').value.reset()
    assert api.option('multi').owner.isdefault()
    assert api.option('multi').value.get() == [['val']]
    api.option('multi').value.set([['val1']])
    assert api.option('multi').owner.get() == owner
    assert api.option('multi').value.get() == [['val1']]


def test_callback_submulti_list():
    multi = StrOption('multi', '', multi=submulti, callback=return_list)
    od_ = OptionDescription('od', '', [multi])
    cfg = Config(od_)
    cfg.read_write()
    api = getapi(cfg)
    owner = cfg.cfgimpl_get_settings().getowner()
    assert api.option('multi').value.get() == [['val', 'val']]
    assert api.option('multi').owner.isdefault()
    api.option('multi').value.set([['val', 'val'], undefined])
    assert api.option('multi').owner.get() == owner
    assert api.option('multi').value.get() == [['val', 'val'], ['val', 'val']]
    api.option('multi').value.set([['val', 'val'], undefined, undefined])
    assert api.option('multi').value.get() == [['val', 'val'], ['val', 'val'], ['val', 'val']]
    api.option('multi').value.reset()
    assert api.option('multi').owner.isdefault()


def test_callback_submulti_list_list():
    multi = StrOption('multi', '', multi=submulti, callback=return_list2)
    od = OptionDescription('od', '', [multi])
    cfg = Config(od)
    cfg.read_write()
    api = getapi(cfg)
    owner = api.owner.get()
    assert owner == 'user'
    assert api.option('multi').value.get() == [['val', 'val']]
    assert api.option('multi').owner.isdefault()
    api.option('multi').value.set([['val', 'val'], undefined])
    assert api.option('multi').owner.get() == owner
    assert api.option('multi').value.get() == [['val', 'val'], []]
    api.option('multi').value.reset()
    assert api.option('multi').owner.isdefault()


#FIXME
#def test_multi_submulti_meta():
#    multi = StrOption('multi', '', multi=submulti)
#    od = OptionDescription('od', '', [multi])
#    conf1 = Config(od, session_id='conf1')
#    conf1.read_write()
#    conf2 = Config(od, session_id='conf2')
#    conf2.read_write()
#    meta = MetaConfig([conf1, conf2])
#    meta.read_write()
#    meta.multi = [['val']]
#    assert meta.multi == [['val']]
#    multi = conf1.multi[0]
#    multi.append()
#    assert conf1.multi == [['val', None]]
#    assert meta.multi == [['val']]