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

# Copyright 2008-2012 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 os
import sys
from os import path
from itertools import *
from calculate.lib.datavars import (TableVariable,Variable,ReadonlyVariable,
                                   VariableError)
import calculate.lib.cl_template as cl_template
from calculate.lib.utils.files import listDirectory,process,PIPE

from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_lib3',sys.modules[__name__])

_envData = [('default', '/etc/calculate/calculate3.env'),
             ('local', '/var/calculate/calculate3.env'),
             ('remote', '/var/calculate/remote/calculate3.env')]

class VariableClEnvData(TableVariable):
    """
    Aliases and path to ini files
    """
    source = ["cl_env_location","cl_env_path"]

class VariableClEnvLocation(ReadonlyVariable):
    """
    Aliases to ini files (from cl_env_data)
    """
    type = 'list'
    value = list(zip(*_envData)[0])

class VariableClEnvPath(Variable):
    """
    Path to ini files (from cl_env_data)
    """
    type = 'list'
    value = list(zip(*_envData)[1])

class VariableClTemplateData(TableVariable):
    """
    Aliases to templates path
    """
    source = ["cl_template_location","cl_template_path"]

class VariableClTemplateLocation(Variable):
    """
    Name to templates
    """
    type = 'list'
    value = ["overlay","local","remote"]


class VariableClTemplatePath(Variable):
    """
    Path to information file on server
    """
    type = 'list'
    value = ["/var/lib/layman/calculate/profiles/templates",
             "/var/calculate/templates",
             "/var/calculate/remote/templates"]

class VariableClEnvServerPath(ReadonlyVariable):
    """
    Path to server environment
    """
    value = '/var/calculate/remote/server.env'

class VariableClTemplateCltPath(ReadonlyVariable):
    """
    Paths to clt-template files
    """
    type = 'list'

    def get(self):
        """
        Clt templates path is /etc and CONFIG_PROTECT
        """
        if "CONFIG_PROTECT" in os.environ:
            protectPaths = ["/etc"] + filter(lambda x: x.strip(),
                                      os.environ["CONFIG_PROTECT"].split(" "))
        else:
            protectPaths = ["/etc", "/usr/share/X11/xkb", "var/lib/hsqldb",
                            "/usr/share/config"]
        return filter(path.exists, protectPaths)

class VariableClRootPath(Variable):
    """
    Path to directory relative which perform joining templates to system files
    (sandbox)
    """
    value = '/'

class VariableClRootPathNext(Variable):
    """
    Path to directory relative which perform joining templates to system files
    (sandbox). This set for configure packages specified throug merge=
    """
    def get(self):
        return self.Get('cl_root_path')

class VariableClChrootPath(ReadonlyVariable):
    """
    Path to directory which contain other system
    """
    value = '/'

class VariableClPassStep(Variable):
    """
    Pass for templates join 1,2,3,4,5 and etc
    """

class VariableClPassFile(Variable):
    """
    Template file performed at now
    """

class VariableClBelongPkg(ReadonlyVariable):
    """
    This variable work with template function belong(package_name)
    if the variable is defined then will use only template, which 
    has package_name in belong equal value of this variable or
    hasn't belong function
    (package_name == value of cl_belong_pkg)
    """
    type = "list"

class VariableClBelongPkgNew(ReadonlyVariable):
    """
    New variable value for cl_belong_pkg
    """
    type = "list"

class VariableClBelongPkgPass(ReadonlyVariable):
    """
    Performed packages
    """
    type = "list"

class VariableClAction(ReadonlyVariable):
    """
    Program action
    Example: install, uninstall, merge, domain, undomain, system, desktop
    """

class VariableClPassState(ReadonlyVariable):
    """
    Program state
    specifies addition to cl_pass_action for needing
    """

class VariableClMerges(Variable):
    """
    Programs have templates setup
    """
    type = 'list'

    def get(self):
        try:
            config = cl_template.iniParser('/etc/calculate/calculate2.env')
            val = config.getVar('main','cl_merges')
            return val.encode('utf-8').split(',')
        except:
            pass
        return []

class VariableClAutoupdateSet(Variable):
    """
    (on or off) autoupdate config from install program
    """
    type = 'boolean'
    value = 'off'

    def get(self):
        try:
            config = cl_template.iniParser('/etc/calculate/calculate2.env')
            val = config.getVar('main','cl_autoupdate_set')
            return val.encode('utf-8')
        except:
            pass
        return []

class VariableClWsdl(Variable):
    """
    Packages with wsdl
    """
    type = "list-choice"

    def choice(self):
        return self.Get('cl_wsdl_available')

class VariableClWsdlAvailable(ReadonlyVariable):
    """
    Packages which has wsdl interfaces
    """
    type = "list"
    
    def get(self):
        sitePackages = map(lambda x:path.join(x,"calculate"),
                       filter(lambda x:x.endswith('site-packages') and \
                                       x.startswith('/usr/lib'),sys.path))
        retList = []
        for module,modDir in chain(*map(lambda x:map(lambda y:(path.basename(y),y),
                             listDirectory(x,True,True)),sitePackages)):
            if path.exists(path.join(modDir,"cl_wsdl_%s.py"%module)):
                if not "calculate-%s"%module in retList:
                    retList.append("calculate-%s"%module)
        return retList

class VariableClConfigProtect(ReadonlyVariable):
    """
    Value of CONFIG_PROTECT after source /etc/profile, and /etc append
    """
    type = "list"

    def get(self):
        displayEnv = process('/bin/bash',"-c","source /etc/profile;env",
                             stdout=PIPE)
        for line in displayEnv:
            if line.startswith("CONFIG_PROTECT="):
                configProtect=line.rstrip().partition('=')[2].split()
                break
        else:
            configProtect = []
        configProtect.append('/etc')
        return configProtect
