#!/usr/bin/env python

# setup.py --- Setup script for calculate-server

#Copyright 2008 Calculate Pack, http://www.calculate-linux.ru
#
#  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 glob
import sys
import re
from distutils.core import setup, Extension
from distutils.command.build_ext import build_ext
from distutils.command.install_lib import install_lib
from distutils.command.build_scripts import build_scripts
from distutils.command.install_scripts import install_scripts

data_files = []

var_data_files = [("/var/calculate/server-profile",[]),
                  ("/var/calculate/server-data",[])]

data_dirs_local = ['profile','ldif']
share_calculate_dir = "/usr/share/calculate/"
data_dirs_share = ['i18n']

data_files += var_data_files

def scanDirs(profilesDirs):
    """Recursive scanning directories"""
    dirs = []
    class dirProf:
        def __init__(self):
            self.baseDir = False
            self.dirs = []
            self.files = []
    def getFilesDir(dirP, dirname,names):
        if '/.svn' in dirname:
            return False
        for nameFile in names:
            absNameFile = dirname + "/" + nameFile
            if '/.svn' in absNameFile:
                continue
            if os.path.isfile(absNameFile):
                dirP.files.append(absNameFile)
            elif os.path.isdir(absNameFile):
                dirP.dirs.append(absNameFile)
        return True
    for profileDir in profilesDirs:
        if profileDir:
            dirP = dirProf()
            dirP.baseDir = profileDir
            dirs.append(dirP)
            os.path.walk(profileDir,getFilesDir, dirP)
    return dirs

def create_data_files (data_dirs, prefix=""):
    test1_files = []
    data_files = []
    dirs = scanDirs(data_dirs)
    i = 0
    for obj in dirs:
        if not obj.dirs:
            obj.dirs.append(data_dirs[i])
        i += 1
    for obj in dirs:
        files_obj_dirs = []
        for dir_name in obj.dirs:
            for file_name in obj.files:
                if re.match(dir_name,file_name):
                    files_obj_dirs.append(dir_name)
                    break
        for files_obj_dir in files_obj_dirs:
            obj.dirs.remove(files_obj_dir)
        files_obj_dirs.sort(lambda x, y: cmp(len(y), len(x)))
        for dir_name in files_obj_dirs:
            wr_sp = (prefix+dir_name,[])
            file_dirs = []
            for file_name in obj.files:
                if re.match(dir_name,file_name):
                    file_dirs.append(file_name)
            for file_name in file_dirs:
                wr_sp[1].append(file_name)
                obj.files.remove(file_name)
            test1_files.append(wr_sp)
    test1_files.reverse()
    test2_files = []
    for obj in dirs:
        for dir_name in obj.dirs:
            wr_sp = (prefix+dir_name,[])
            test2_files.append(wr_sp)

    test1_files = test2_files + test1_files
    return test1_files

data_files += create_data_files (data_dirs_local)
data_files += create_data_files (data_dirs_share, share_calculate_dir)

class cl_build_ext(build_ext):
    """Class for compile C file to binary execute file"""
    backup_func = {}
    def build_extension(self, ext):
        if ext.name.split('.')[-1] == 'repbin':
            if not self.backup_func:
                self.backup_func['get_ext_filename'] = self.get_ext_filename
                self.backup_func['link_shared_object'] =\
                                            self.compiler.link_shared_object
            self.get_ext_filename = lambda ext_name:\
                                        os.path.join(*ext_name.split('.'))
            self.compiler.link_shared_object = lambda *arg, **argv:\
                                                self.compiler.link(\
                                                self.compiler.EXECUTABLE,\
                                                *arg, **argv)
        else:
            if self.backup_func:
                self.get_ext_filename = self.backup_func['get_ext_filename']
                self.compiler.link_shared_object =\
                                        self.backup_func['link_shared_object']
        build_ext.build_extension(self, ext)

class cl_install(install_lib):
    def run (self):
        install_lib.run(self)
        for path in self.get_outputs():
            bin_file = os.path.split(path)[1]
            if bin_file == 'repbin':
                os.chmod(path, 0104711)
                break

class cl_build_scripts(build_scripts):
    """Class for build scripts"""
    def run (self):
        scripts = ['./scripts/proxy', './scripts/dhcp'] 
        backup_build_dir = self.build_dir
        backup_scripts = filter(lambda x: not x in scripts, self.scripts)
        self.scripts = scripts
        self.build_dir = self.build_dir + "-bin"
        build_scripts.run(self)
        self.scripts = backup_scripts
        self.build_dir = backup_build_dir
        build_scripts.run(self)

class cl_install_scripts(install_scripts):
    """Class for install scripts"""
    def run (self):
        backup_install_dir = self.install_dir
        backup_build_dir = self.build_dir
        cl_cmd_obj = self.distribution.get_command_obj("install")
        self.build_dir = self.build_dir + "-bin"
        self.install_dir = os.path.join(cl_cmd_obj.install_data,"bin")
        install_scripts.run(self)
        self.build_dir = backup_build_dir
        self.install_dir = backup_install_dir
        install_scripts.run(self)


exec_file = Extension('calculate-server.bin.repbin',
                      sources = ['./bin/repbin.c'])
setup(
    name = 'calculate-server',
    version = "2.1.6",
    description = "The program for configuring server-data linux",
    author = "Calculate Pack",
    author_email = "support@calculate.ru",
    url = "http://calculate-linux.ru",
    license = "http://www.apache.org/licenses/LICENSE-2.0",
    package_dir = {'calculate-server': "."},
    packages = ['calculate-server.pym'],
    data_files = data_files,
    scripts=["./scripts/cl-useradd",
             "./scripts/cl-userdel",
             "./scripts/cl-usermod",
             "./scripts/cl-groupadd",
             "./scripts/cl-groupmod",
             "./scripts/cl-groupdel",
             "./scripts/cl-passwd",
             "./scripts/cl-setup",
             "./scripts/cl-backup",
             "./scripts/cl-update",
             "./scripts/cl-rebuild",
             "./scripts/cl-replication",
             "./scripts/repldap",
             "./scripts/.reprun",
             "./scripts/replcron",
             "./scripts/cl-info",
             "./scripts/proxy",
             "./scripts/cl-dns-recadd",
             "./scripts/cl-dns-recdel",
             "./scripts/cl-dns-recmod",
             "./scripts/cl-dns-zoneadd",
             "./scripts/cl-dns-zonedel",
             "./scripts/cl-dns-zonemod",
             "./scripts/cl-dhcp-netadd",
             "./scripts/cl-dhcp-netdel",
             "./scripts/cl-dhcp-netmod",
             "./scripts/cl-dhcp-hostadd",
             "./scripts/cl-dhcp-hostdel",
             "./scripts/cl-dhcp-hostmod",
             "./scripts/dhcp"],
    ext_modules = [exec_file],
    cmdclass={'build_ext':cl_build_ext,
              'install_lib':cl_install,
              'build_scripts':cl_build_scripts,
              'install_scripts':cl_install_scripts},
)
