# coding: utf-8
"frozen and hidden values" 
import autopath
from py.test import raises

from config import *
from option import *

def make_description():
    gcoption = ChoiceOption('name', 'GC name', ['ref', 'framework'], 'ref')
    gcoption.set_mode("expert")
    gcdummy = BoolOption('dummy', 'dummy', default=False)
    # hidding dummy here
    gcdummy.hide()
    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")

    wantref_option = BoolOption('wantref', 'Test requires', default=False,
                                    requires=[('gc.name', 'ref')])
    wantframework_option = BoolOption('wantframework', 'Test requires',
                                      default=False,
                                      requires=[('gc.name', 'framework')])
    
    # ____________________________________________________________
    booloptiontwo = BoolOption('booltwo', 'Test boolean option two', default=False)
    subgroup = OptionDescription('subgroup', '', [booloptiontwo])
    # ____________________________________________________________
    
    gcgroup = OptionDescription('gc', '', [subgroup, gcoption, gcdummy, floatoption])
    gcgroup.set_mode("expert")
    descr = OptionDescription('trs', '', [gcgroup, booloption, objspaceoption,
                                           wantref_option, stroption,
                                           wantframework_option,
                                           intoption])
    return descr
#____________________________________________________________
#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)
    wantref_option = BoolOption('wantref', 'Test requires', default=False,
                                    requires=['boolop'])
    wantframework_option = BoolOption('wantframework', 'Test requires',
                                      default=False,
                                      requires=['boolop'])
    
    gcgroup = OptionDescription('gc', '', [gcoption, gcdummy, floatoption])
    descr = OptionDescription('tiramisu', '', [gcgroup, booloption, objspaceoption,
                                           wantref_option, stroption,
                                           wantframework_option,
                                           intoption, boolop])
    return descr

def test_freeze_one_option():
    "freeze an option "
    descr = make_description_freeze()
    conf = Config(descr)
    #freeze only one option
    conf.gc._cfgimpl_descr.dummy.freeze()
    assert conf.gc.dummy == False
    raises(TypeError, "conf.gc.dummy = True")

def test_frozen_value():
    "setattr a frozen value at the config level"
    s = StrOption("string", "", default="string")
    descr = OptionDescription("options", "", [s])
    config = Config(descr)
    s.freeze()
    raises(ConfigError, 'config.string = "egg"')

def test_freeze():
    "freeze a whole configuration object"
    descr = make_description()
    conf = Config(descr)
    conf.cfgimpl_freeze()
    raises(ConfigError, "conf.gc.name = 'try to modify'")
# ____________________________________________________________
def test_is_hidden():
    descr = make_description()
    config = Config(descr)
    assert config.gc._cfgimpl_descr.dummy._is_hidden() == True
    # setattr
    raises(HiddenOptionError, "config.gc.dummy == False")
    # getattr
    raises(HiddenOptionError, "config.gc.dummy")
    # I want to access to this option anyway
    path = 'gc.dummy'
    homeconfig, name = config._cfgimpl_get_home_by_path(path)
    assert homeconfig._cfgimpl_values[name] == False

def test_group_is_hidden():
    descr = make_description()
    config = Config(descr)
    gc = config.unwrap_from_path('gc')
    gc.hide()
    dummy = config.unwrap_from_path('gc.dummy')
    raises(HiddenOptionError, "config.gc.dummy")
    assert gc._is_hidden()
    raises(HiddenOptionError, "config.gc.float")
    # manually set the subconfigs to "show"
    gc.show()
    assert gc._is_hidden() == False
    assert config.gc.float == 2.3
    #dummy est en hide
    raises(HiddenOptionError, "config.gc.dummy == False")
    
def test_global_show():
    descr = make_description()
    config = Config(descr)
    assert config.gc._cfgimpl_descr.dummy._is_hidden() == True
    raises(HiddenOptionError, "config.gc.dummy == False")

def test_with_many_subgroups():
    descr = make_description()
    config = Config(descr)
    assert config.gc.subgroup._cfgimpl_descr.booltwo._is_hidden() == False
    assert config.gc.subgroup.booltwo == False
    config.gc.subgroup._cfgimpl_descr.booltwo.hide()
    path = 'gc.subgroup.booltwo'
    homeconfig, name = config._cfgimpl_get_home_by_path(path)
    assert name == "booltwo"
    option = getattr(homeconfig._cfgimpl_descr, name)
    assert option._is_hidden()

def test_option_mode():
    descr = make_description()
    config = Config(descr)
    assert config.gc._cfgimpl_descr.name.get_mode() == 'expert'
    assert config._cfgimpl_descr.gc.get_mode() == 'expert'
    
