#-*- 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 re
import sys

import sys
import re
from os import path
from files import listDirectory, readFile
from common import getTupleVersion

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

reVerSplit = re.compile(r"^(?:.*/var/db/pkg/)?(?:(\w+-\w+)/)?(.*?)-(([^-]+?)"
                         "(?:-(r\d+))?)(?:.(tbz2))?$",re.S)
def reVerSplitToPV(x):
    """Convert match from reVerSplit to PV hash"""
    if type(x) == str:
        x = reVerSplit.search(x)
    if x:
        match = x.groups()
        return {'CATEGORY':match[0] or "",
                'PN':match[1],
                'PF':"%s-%s"%(match[1],match[2]),
                'P':"%s-%s"%(match[1],match[3]),
                'PV':match[3],
                'PR':match[4] or "r0",
                'PVR':match[2]}
    return {'PN':"",
            'PF':"",
            'P':"",
            'PV':"",
            'PR':"",
            'PVR':""}.copy()

def getPkgUses(fullpkg):
    """Get USE and IUSE from package"""
    category,slash,pkg = fullpkg.partition('/')
    pkgCategory = '/var/db/pkg/{0}'.format(category)
    packages = filter(lambda x:x['PN'] == pkg,
               map(reVerSplitToPV,
               filter(lambda x:x,
               map(lambda x:reVerSplit.search(x),
               listDirectory(pkgCategory)))))
    if not packages:
        return None
    usePath = path.join(pkgCategory,packages[-1]['PF'],"USE")
    iusePath = path.join(pkgCategory,packages[-1]['PF'],"IUSE")
    iuse = readFile(iusePath).strip().split()
    use = readFile(usePath).strip().split()
    return (map(lambda x:x[1:] if x.startswith("+") else x,
            filter(lambda x:x,
            use)),
            map(lambda x:x[1:] if x.startswith("+") else x,
            filter(lambda x:x,
            iuse)))

def isPkgInstalled(pkg,prefix='/',sortByVersion=False):
    """Check is package installed"""
    pkgDir = path.join(prefix,'var/db/pkg')
    if "/" in pkg:
        category,op,pkg = pkg.partition('/')
        res = map(lambda x:x.update({'CATEGORY':category}) or x,
                   filter(lambda x:x['PN'] == pkg,
                   map(reVerSplitToPV,
                   listDirectory(path.join(pkgDir,category)))))
        if len(res)>1 and sortByVersion:
            return sorted(res,key=lambda x:getTupleVersion(x['PVR']))
        else:
            return res
    else:
        return filter(lambda x: filter(lambda y:y['PN'] == pkg,
                                map(reVerSplitToPV,
                                listDirectory(x))),
               listDirectory(pkgDir,fullPath=True))

def getPkgSlot(pkg,prefix='/'):
    """Get package slot"""
    pkgs = isPkgInstalled(pkg,prefix)
    pkgDir = path.join(prefix,'var/db/pkg')
    return map(lambda x:readFile(path.join(pkgDir,x['CATEGORY'],
                                           x['PF'],"SLOT")).strip(),
           pkgs)

def getPkgActiveUses(fullpkg):
    """Get active uses from package"""
    res = getPkgUses(fullpkg)
    if not res:
        return None
    return list(set(res[0]) & set(res[1]))

def getSquashList():
    """Get supprted squashfs compressions method"""
    wantMethod = set(["lzo","lzma","xz","gzip"])
    usesSquashFs = getPkgActiveUses("sys-fs/squashfs-tools")
    if not usesSquashFs:
        return ["gzip"]
    else:
        pkgInfo = isPkgInstalled('sys-fs/squashfs-tools')
        if pkgInfo and pkgInfo[0]['PV']:
            pkgVer = getTupleVersion(pkgInfo[0]['PV'])
            gzipVer = getTupleVersion('4.2')
            if pkgVer >= gzipVer:
                usesSquashFs.append('gzip')
        return map(lambda x:{"lzma":"xz"}.get(x,x),
               list(set(usesSquashFs) & wantMethod))

def searchProfile(dirpath,configname):
    """Search profile"""
    paths = []
    def search(dirpath):
        parentpath = path.join(dirpath,"parent")
        if path.exists(parentpath):
            for line in open(parentpath,'r'):
                search(path.join(dirpath,line.strip()))
        fullconfig = path.join(dirpath,configname)
        if path.exists(fullconfig):
            paths.append(fullconfig)
    search(dirpath)
    return paths
