# -*- Python -*-

import glob
import sys
import distutils.sysconfig
import shutil, stat
import re
import os
import os.path
from helpers import *
import dbhash
import SCons
import commands

print """Please remember that SCons does NOT automatically use your shell
environment variables. This script uses PKG_CONFIG_PATH explicitly."""

SConsignFile('scons-signatures-db', dbhash)

opts = Options('SCustomize')

default_module_prefix = os.path.join(distutils.sysconfig.get_python_lib(),'jppy')

opts.Add(PathOption('python_module_prefix','Prefix to install python module to',
                    default_module_prefix,PathOption.PathAccept))
opts.Add(PathOption('python_bin_module_prefix','Prefix to install python binary module to',
                    default_module_prefix,PathOption.PathAccept))
opts.Add(PathOption('prefix','Prefix to install /bin/<scripts> to',
                    '/usr/local'))
opts.Add(PathOption('mx_datetime_includes','Path to mx/mxDateTime.h',
                    '/usr/include/python%s' % sys.version[0:3], PathOption.PathIsDir ))
opts.Add(PathOption('python_includes','Path to Python.h',
                    '/usr/include/python%s' % sys.version[0:3], PathOption.PathIsDir ))
opts.Add(PathOption('pisock_includes','Path to pi-socket.h','/usr/include'))
opts.Add(PathOption('pisock_library','Path to libpisock.so','/usr/lib'))
opts.Add(PathOption('jppyroot','Install jppy to a different root than /',
                    '/',PathOption.PathIsDirCreate))
opts.Add(PathOption('jppyguiroot','Install jppy\'s gui to a different root than /',
                    '/',PathOption.PathIsDirCreate))
opts.Add(PathOption('jpilotroot','Install jpilot plugins to a different root than /',
                    '/',PathOption.PathIsDirCreate))
opts.Add(PackageOption('rpathoverride','Link with an rpath','no'))
opts.Add(BoolOption('test','Do you want to run the tests?','yes'))
opts.Add(BoolOption('profile','Do you want compile with profiling?','no'))
opts.Add('python_version','Python library version', sys.version[0:3])

env = Environment(options=opts,
                  CCFLAGS=['-g'],
                  CPPPATH=['${mx_datetime_includes}',
                           '${pisock_includes}',
                           '${python_includes}',
                           '#/libversit_src'])

if env['python_module_prefix'] != default_module_prefix and \
   env['python_bin_module_prefix'] == default_module_prefix:
     print "Making python_bin_module_prefix match your non-default python_module_prefix"
     env['python_bin_module_prefix'] = env['python_module_prefix']

if env['profile']:
     env.Append(CCFLAGS='-pg')
     env.Append(LINKFLAGS='-pg')

SWIGScanner = SCons.Scanner.ClassicCPP(    "SWIGScan",
                                           ".i",
                                           "CPPPATH",
                                           """^[ \t]*[%,#][
                                           \t]*(?:include|import)[
                                           \t]*(<|")([^>"]+)(>|")""")
""" " """ # fix XEmacs' python syntax highlighting.
                                                     
env['SCANNERS'] += [SWIGScanner]


for take_from_env in ["PKG_CONFIG_PATH"]:
     if os.environ.has_key(take_from_env):
          env['ENV'][take_from_env] = os.environ[take_from_env]

if env['rpathoverride']:
     if env['rpathoverride'] in (1,'yes'):
          print "rpathoverride must be a path"
     else:
          env.Append(LINKFLAGS = '-Wl,--rpath=$rpathoverride -L$rpathoverride')

opts.Save('SCustomize',env)

config = env.Configure(custom_tests={'CheckPKGConfig' : CheckPKGConfig, 
                                     'CheckPKG' : CheckPKG })

Help(opts.GenerateHelpText(env))

if not config.CheckPKGConfig('0.15.0'): 
     print 'pkg-config >= 0.15.0 not found.' 
     Exit(1) 
 
if not config.CheckPKG('gtk+-2.0 >= 2.4.0'): 
     print 'gtk+-2.0 >= 2.4.0 not found.' 
     Exit(1)

if not config.CheckPKG('glib-2.0 >= 2.4.0'): 
     print 'glib-2.0 >= 2.4.0 not found.' 
     Exit(1)

if not config.CheckPKG('pygtk-2.0 >= 2.4.0'): 
     print 'pygtk-2.0 >= 2.4.0 not found.' 
     Exit(1)

env.ParseConfig('pkg-config --cflags --libs glib-2.0')
env.ParseConfig('pkg-config --cflags --libs gtk+-2.0')
     
#standard stuff
for hdr in [['Python.h','mx/mxDateTime.h']]:
     if not config.CheckHeader(hdr):
          print "You need '%s' to compile this program" % hdr
          Exit(1)
          
vars = distutils.sysconfig.get_config_vars('CC', 'CXX', 'OPT', 'BASECFLAGS',
                                           'CCSHARED', 'LDSHARED', 'SO') 
for i in range(len(vars)): 
    if vars[i] is None: 
        vars[i] = "" 
 
(pycc, pycxx, pyopt, pybasecflags, pyccshared, pyldshared, pyso_ext) = vars 


current_version = open("current-version", "r").read().strip()
top_version, major_version, minor_version = current_version.split(".")
if "~"  in minor_version:
     minor_version, extra_version = minor_version.split("~")
else:
     extra_version = ""

DEFINES_ALL=["JPPY_VERSION=%s" % current_version,
             "JPPY_MAJOR_VERSION=%s" % major_version,
             "JPPY_MINOR_VERSION=%s" % minor_version,
             "JPPY_EXTRA_VERSION=\\\"%s\\\"" % extra_version,             
             "ENABLE_GTK2"]
env.AppendUnique(CPPDEFINES=DEFINES_ALL)

env = config.Finish()

env['python_module_path'] = os.path.join(env['jppyroot'],
                                         env['python_module_prefix'][1:])
env['python_bin_module_path'] = os.path.join(env['jppyroot'],
                                         env['python_bin_module_prefix'][1:])
env['python_gui_module_path'] = os.path.join(env['jppyguiroot'],
                                             env['python_module_prefix'][1:])
env['jpilot_plugin_prefix'] = os.path.join(env['prefix'],
                                           "lib/jpilot/plugins")
env['jpilot_plugin_path'] = os.path.join(env['jpilotroot'],
                                         env['jpilot_plugin_prefix'][1:])

######### Jpilot
jpilotEnv = env.Clone()
jpilotConfig = jpilotEnv.Configure()
if not jpilotConfig.CheckLibWithHeader('libpisock',
                                       'pi-socket.h','C','pi_socket_connected(0);'):
     print "You need libpisock to compile this program"
     Exit(1)
jpilotConfig.Finish()
jpilot_sources = ['log', 'libplugin', 'utils', 'prefs',
                  'plugins', 'sync', 'japanese', 'cp1250',
                  'russian', 'password', 'category', 'otherconv']
# a bit of a hack. Scons doesn't support shared objects in static libraries.
libjpilot = jpilotEnv.StaticLibrary(target='jpilot_src/jppy_jpilot',
                                    source = ["jpilot_src/%s.c" % x for x in jpilot_sources],
                                    CCFLAGS="$CCFLAGS -fPIC")
libjpilot[0].attributes.shared = True


######### Jppy
jppyEnv = jpilotEnv.Clone()
jppyEnv.ParseConfig('pkg-config --cflags --libs pygtk-2.0')      
jppymodule = jppyEnv.SharedLibrary(target = 'jppy/__jpilotmodule',
                                   source = ['python_module_src/jpilot.i',
                                             'python_module_src/move_into_libpisock.c',
                                             'python_module_src/jpilot_helpers.c',
                                             libjpilot] +
                                   glob.glob("python_module_src/pytype*.c") +
                                   ["libversit_src/%s" % x for x in ["vcc.y",
                                                                     "vobject.c",
                                                                     "vcaltmp.c"]],
                                   SHLIBPREFIX="",
                                   SHLIBSUFFIX=pyso_ext,
                                   SWIGFLAGS="-python -outdir ./jppy/")

######### Jpilot Plugins

pluginEnv = env.Clone(SHLIBSUFFIX=pyso_ext,
                      SHLIBPREFIX="lib")
pluginEnv.Append(CPPPATH=['#/jpilot_src'])

pluginEnv.Append(CPPDEFINES=['JPILOT_PLUGIN_PREFIX=\\"$jpilot_plugin_prefix\\"'])


jppyPluginEnv = pluginEnv.Clone()
jppyPluginEnv.Append(LINKFLAGS=distutils.sysconfig.get_config_var('LINKFORSHARED'))
jppyPluginConfig = jppyPluginEnv.Configure()
if not jppyPluginConfig.CheckLibWithHeader("libpython%s" % env['python_version'], 
                                           'Python.h','C','PyErr_Clear();'): 
     print "You need libpython%s.so to compile this program" % env['python_version']
     Exit(1) 
jppyPluginConfig.Finish()
python_library_filename = commands.getoutput("./find-python-library-name.sh libpython%s.so" % env['python_version'])
jppyPluginEnv.Append(CPPDEFINES=['PYTHON_SHARED_LIB=\\"%s\\"' % python_library_filename])

jpilot_plugins = []

jpilot_plugins.append(jppyPluginEnv.SharedLibrary(target = "jpilot_plugins/jppy",
                                                  source = "jpilot_plugins/jppy.c"))

jpilot_plugins.append(pluginEnv.SharedLibrary(target = "jpilot_plugins/sync-Contacts",
                                              source = "jpilot_plugins/sync-Contacts.c"))

jpilot_plugins.append(pluginEnv.SharedLibrary(target = "jpilot_plugins/sync-PTimLogA",
                                              source = "jpilot_plugins/sync-PTimLogA.c"))

jpilot_plugins.append(pluginEnv.SharedLibrary(target = "jpilot_plugins/sync-PTimLogB",
                                              source = "jpilot_plugins/sync-PTimLogB.c"))

jpilot_plugins.append(pluginEnv.SharedLibrary(target = "jpilot_plugins/sync-PTimLogC",
                                              source = "jpilot_plugins/sync-PTimLogC.c"))

jpilot_plugins.append(File('#jpilot_plugins/jpilot_site.py'))
     

######### Tests
if env['test']:
     SConscript(dirs=['tests'],exports=['env','jppymodule'])

first_line_re = re.compile('^#!.*python[0-9.]*([ \t].*)?$')
tokens_re = re.compile('@@([^@]*)@@')

def copyFunc(dest, source, env):
    f = open(source, "r")
    first_line = f.readline()
    rest = f.read()

    first_line_match = first_line_re.match(first_line)
    tokens_match     = tokens_re.search(rest)
    if first_line_match or tokens_match:
         for token in tokens_re.finditer(rest):
              if env.has_key(token.group(1)):
                   print "Replacing %s with %s" % (token.group(0), env[token.group(1)])
                   rest = rest.replace(token.group(0), env[token.group(1)])
         outf = open(dest, "w")
         if first_line_match:
              post_interp = first_line_match.group(1) or ''
              if not distutils.sysconfig.python_build:
                   outf.write("#!%s%s\n" % 
                              (os.path.normpath(sys.executable),
                               post_interp))
              else:
                   outf.write("#!%s%s\n" %
                              (os.path.join(
                        distutils.sysconfig.get_config_var("BINDIR"),
                        "python" + sysconfig.get_config_var("EXE")),
                               post_interp))
         else:
              outf.writelines([first_line])
         outf.write(rest)
         outf.close()
         f.close()
    else:
         f.close()
         shutil.copy(source, dest)
    if env.has_key("INSTALL_PERMS"):
         os.chmod(dest, env['INSTALL_PERMS'])
    else:
         os.chmod(dest, 0644)         
    return 0

######### Install
env['INSTALL'] = copyFunc

env.Alias('install', Dir(env['python_module_path']))
env.Install(env['python_module_path'], glob.glob("jppy/*py"))
env.Install(env['python_bin_module_path'], jppymodule)

env.Install(os.path.join(env['python_gui_module_path'],"gui"),
            [glob.glob("jppy/gui/*.py") +
             glob.glob("jppy/gui/*.txt") +
             glob.glob("jppy/gui/*.glade")])


env.Alias('install', Dir(env['jpilot_plugin_path']))
env.Install(env['jpilot_plugin_path'], jpilot_plugins)

SConscript(dirs=['scripts'],exports=['env'])
