#-*- coding: utf-8 -*-

# Copyright 2011-2013 Calculate Ltd. http://www.calculate-linux.org
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.


import sys, os
import re

from calculate.lib.datavars import Variable,DataVarsError,VariableError
from calculate.lib import datavars
from calculate.lib.cl_lang import setLocalTranslate,getLazyLocalTranslate
setLocalTranslate('cl_core3',sys.modules[__name__])
__ = getLazyLocalTranslate(_)


VARIABLE,MODE,LOCATION,VALUE = 0,1,2,3

class Variables:
    def writeVariables(self,vardata):
        """
        Write variable to env files, or delete from env files
        """
        dv = self.clVars
        data = filter(lambda x:x[LOCATION] or \
                    not x[LOCATION] and \
                    dv.isFromIni(x[VARIABLE].rpartition('.')[2]),
               vardata)
        if data:
            head = [_("Variable"),_("Mode"), _("Location"),
                    _("Value")]
            self.printTable(_("List of variables"), head, data)
            for varname,mode,location,value in data:
                if location:
                    value = dv.unserialize(dv.getInfo(varname).type,str(value))
                section,op,varname = varname.rpartition('.')
                if not location:
                    for location in dv.Get('main.cl_env_location'):
                        if not dv.Delete(varname,location,header=section):
                            self.printWARNING(
                                _("Failed to delete variable {var} from {location}").format(
                                  var=varname,location=location))
                else:
                    if varname in dv.iniCache:
                        oldValue = dv.unserialize(dv.getInfo(varname).type,
                                        str(dv.iniCache[varname]['value']))
                    else:
                        oldValue = None
                    if value != oldValue:
                        dv.Write(varname,value,location=location,header=section)
        else:
            self.printSUCCESS("Nothing to set")
        return True

    def showVariables(self,showVal,filterVal,vardata):
        """
        Show variables by cl_variable_filter
        """
        dv = self.clVars
        removeQuotes = lambda x: x if x != "''" else ""
        reIndex = re.compile("((?:\w+\.)?(\w+))(?:\[(\d+)\])")
        if showVal:
            index = reIndex.search(showVal)
            if index:
                varname = index.group(1)
                index = int(index.group(3))
            else:
                varname = showVal
            prevVal = str(dv.Select('cl_variable_value',
                          where='cl_variable_fullname',
                          eq=varname,limit=1))
            if not index is None:
                typeVar = dv.getInfo(varname).type
                val = dv.unserialize(typeVar,prevVal)
                if index < len(val):
                    self.printDefault(removeQuotes(val[index]))
                else:
                    self.printDefault("")
            else:
                self.printDefault(removeQuotes(prevVal))
            return True
        filterFunc = \
            {'all':None,
             'userset' :lambda x:x[LOCATION],
             'writable':lambda x:x[MODE].startswith("w"),
             'system'  :lambda x:x[LOCATION] == "system",
             'local'   :lambda x:x[LOCATION] == "local",
             'remote'  :lambda x:x[LOCATION] == "remote"}.get(filterVal,
                        lambda x:filterVal in x[VARIABLE])
        body = filter(filterFunc,vardata)
        dv.close()
        if body:
            head = [_("Variable"),_("Mode"),
                    _("Location"),_("Value")]
            self.printTable(_("List of variables"), head, body)
            return True
        else:
            self.printWARNING(_("No such variables"))
        return True
