# coding: utf-8
"frozen and hidden values"
import autopath

from tiramisu.option import ChoiceOption, BoolOption, IntOption, FloatOption, \
    StrOption, OptionDescription
from tiramisu.config import Config
from tiramisu.error import PropertiesOptionError


#____________________________________________________________
#freeze
def make_description_freeze():
    gcoption = ChoiceOption('name', 'GC name', ('ref', 'framework'), 'ref')
    gcdummy = BoolOption('dummy', 'dummy', default=False)
    objspaceoption = ChoiceOption('objspace', 'Object space',
                                  ('std', 'thunk'), 'std')
    booloption = BoolOption('bool', 'Test boolean option', default=True)
    intoption = IntOption('int', 'Test int option', default=0)
    floatoption = FloatOption('float', 'Test float option', default=2.3)
    stroption = StrOption('str', 'Test string option', default="abc")
    boolop = BoolOption('boolop', 'Test boolean option op', default=[True], multi=True)
    wantref_option = BoolOption('wantref', 'Test requires', default=False, properties=('force_store_value',),
                                requires=({'option': booloption, 'expected': True, 'action': 'hidden'},))
    wantframework_option = BoolOption('wantframework', 'Test requires',
                                      default=False,
                                      requires=({'option': booloption, 'expected': True, 'action': 'hidden'},))

    gcgroup = OptionDescription('gc', '', [gcoption, gcdummy, floatoption])
    descr = OptionDescription('tiramisu', '', [gcgroup, booloption, objspaceoption,
                              wantref_option, stroption,
                              wantframework_option,
                              intoption, boolop])
    return descr


def test_freeze_whole_config():
    descr = make_description_freeze()
    conf = Config(descr)
    setting = conf.cfgimpl_get_settings()
    conf.read_write()
    setting.append('everything_frozen')
    assert conf.gc.dummy is False
    prop = []
    try:
        conf.gc.dummy = True
    except PropertiesOptionError as err:
        prop = err.proptype
    assert 'frozen' in prop
    setting.remove('everything_frozen')
    conf.gc.dummy = True
    assert conf.gc.dummy is True


def test_freeze_one_option():
    "freeze an option "
    descr = make_description_freeze()
    conf = Config(descr)
    setting = conf.cfgimpl_get_settings()
    conf.read_write()
    #freeze only one option
    dummy = conf.unwrap_from_path('gc.dummy')
    setting[dummy].append('frozen')
    assert conf.gc.dummy is False
    prop = []
    try:
        conf.gc.dummy = True
    except PropertiesOptionError as err:
        prop = err.proptype
    assert 'frozen' in prop


def test_frozen_value():
    "setattr a frozen value at the config level"
    s = StrOption("string", "", default="string")
    descr = OptionDescription("options", "", [s])
    config = Config(descr)
    setting = config.cfgimpl_get_settings()
    config.read_write()
    setting.append('frozen')
    setting[s].append('frozen')
    prop = []
    try:
        config.string = "egg"
    except PropertiesOptionError as err:
        prop = err.proptype
    assert 'frozen' in prop


def test_freeze():
    "freeze a whole configuration object"
    descr = make_description_freeze()
    conf = Config(descr)
    setting = conf.cfgimpl_get_settings()
    conf.read_write()
    setting.append('frozen')
    name = conf.unwrap_from_path("gc.name")
    setting[name].append('frozen')
    prop = []
    try:
        conf.gc.name = 'framework'
    except PropertiesOptionError as err:
        prop = err.proptype
    assert 'frozen' in prop


def test_freeze_multi():
    descr = make_description_freeze()
    conf = Config(descr)
    setting = conf.cfgimpl_get_settings()
    conf.read_write()
    setting.append('frozen')
    obj = conf.unwrap_from_path('boolop')
    setting[obj].append('frozen')
    prop = []
    try:
        conf.boolop = [True]
    except PropertiesOptionError as err:
        prop = err.proptype
    assert 'frozen' in prop


def test_freeze_get_multi():
    descr = make_description_freeze()
    conf = Config(descr)
    setting = conf.cfgimpl_get_settings()
    conf.read_write()
    setting.append('frozen')
    valmulti = conf.boolop
    valmulti.append(False)
    obj = conf.unwrap_from_path('boolop')
    setting[obj].append('frozen')
    prop = []
    try:
        valmulti.append(False)
    except PropertiesOptionError as err:
        prop = err.proptype
    assert 'frozen' in prop


def test_force_store_value():
    descr = make_description_freeze()
    conf = Config(descr)
    assert conf.getowner(conf.unwrap_from_path('wantref')) == 'default'
    conf.wantref
    assert conf.getowner(conf.unwrap_from_path('wantref')) == 'user'


def test_force_store_value_ro():
    descr = make_description_freeze()
    conf = Config(descr)
    conf.read_only()
    assert conf.getowner(conf.unwrap_from_path('wantref')) == 'default'
    conf.wantref
    assert conf.getowner(conf.unwrap_from_path('wantref')) == 'user'