#!/usr/bin/python
#
# Copyright (C) 2004 Federico Di Gregorio <fog@debian.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY
# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.

import sys
import os
import os.path
import optparse
import shutil
import time
import glob
import urllib2
import md5


CG_LIBRARIES = ('libCg.so', 'libCgFX.so', 'libCgGL.so', 'libCgFXGL.so')
CG_PDFS = ('CgManualAddendum.pdf', 'CgReleaseNotes.pdf', 'Cg_Toolkit.pdf',
           'GettingStarted.pdf')

pipe = os.popen('dpkg --print-architecture', 'r')
arch = pipe.read().strip()
pipe.close()

if arch == 'i386':
    CG_URL  = 'ftp://download.nvidia.com/developer/cg/Cg_1.3/Linux/'
    CG_FILE = 'Cg-1.3.0501-0700.i386.tar.gz'
    CG_MD5  = 'c122d853eca52e9863832480dc3ab843'
    CG_USR_LIB = '/usr/lib'
elif arch == 'amd64':
    CG_URL  = 'ftp://download.nvidia.com/developer/cg/Cg_1.3/Linux64/'
    CG_FILE = 'Cg-1.3.0501-0700.x86_64.tar.gz'
    CG_MD5  = 'a9b4cb044e5975783e34edfcb82d5d71'
    CG_USR_LIB = '/usr/lib64'
else:
    sys.stderr.write("Error: architecture %s is not supported\n" % arch)
    sys.exit(1)

def cg_uninstall():
    """Uninstall all components."""
    print "Uninstalling NVIDIA Cg Toolkit components:"

    print "  Cg compiler,",
    try:
        os.unlink('/usr/bin/cgc')
    except OSError:
        pass

    print "header files,",
    shutil.rmtree('/usr/include/Cg', ignore_errors=True)
    shutil.rmtree('/usr/include/CgFX', ignore_errors=True)    

    print "libraries,",
    for l in CG_LIBRARIES:
        try:
            os.unlink(os.path.join(CG_USR_LIB, l))
        except OSError:
            pass

    print "documentation,"
    for l in CG_PDFS:
        try:
            os.unlink(os.path.join('/usr/share/doc/nvidia-cg-toolkit', l))
        except OSError:
            pass

    shutil.rmtree('/usr/share/doc/nvidia-cg-toolkit/html', ignore_errors=True)
    shutil.rmtree('/usr/share/doc/nvidia-cg-toolkit/txt', ignore_errors=True)

    print "  examples,",
    shutil.rmtree('/usr/share/doc/nvidia-cg-toolkit/examples',
                  ignore_errors=True)

    print "manual pages,",
    for f in glob.glob('/usr/share/man/man3/*.3nvidiacg.gz'):
        try:
            os.unlink(f)
        except OSError:
            pass
        
    print "done."
    
def cg_install(filename):
    """Install from give file."""
    print "Checking md5 checksum on " + filename
    md5sum = md5.new(open(filename).read()).hexdigest()
    if md5sum != CG_MD5:
        e = "Error: md5sum mismatch: %s != %s"
        sys.stderr.write(e % (CG_MD5, md5sum))
        sys.exit(2)
        
    target = os.path.join('/tmp', 'cg.%f' % time.time())
    try:
        os.mkdir(target)
    except:
        e = "Error: can't create directory: %s."
        sys.stderr.write(e % target)
        sys.exit(2)

    cg_uninstall()
    
    print "Uncompressing NVIDIA Cg toolkit into " + target
    os.system("/bin/tar xzf %s -C %s" % (filename, target))

    print "Moving files to their final destinations:"

    print "  cg compiler,",
    shutil.move(os.path.join(target, 'usr/bin/cgc'), '/usr/bin/cgc')
    
    print "header files,",
    shutil.move(os.path.join(target, 'usr/include/Cg'), '/usr/include/Cg')
    shutil.move(os.path.join(target, 'usr/include/CgFX'), '/usr/include/CgFX')

    print "libraries,",
    for l in CG_LIBRARIES:
        shutil.move(os.path.join(target, 'usr/lib', l),
                    os.path.join(CG_USR_LIB, l))

    print "documentation,"
    for l in CG_PDFS:
        shutil.move(os.path.join(target, 'usr/local/Cg/docs', l),
                    os.path.join('/usr/share/doc/nvidia-cg-toolkit', l))
    shutil.move(os.path.join(target, 'usr/local/Cg/docs/runtime/html'),
                '/usr/share/doc/nvidia-cg-toolkit/html')
    shutil.move(os.path.join(target, 'usr/local/Cg/docs/runtime/cgGL/html'),
                '/usr/share/doc/nvidia-cg-toolkit/html/cgGL')
    shutil.move(os.path.join(target, 'usr/local/Cg/docs/runtime/txt'),
                '/usr/share/doc/nvidia-cg-toolkit/txt')
    shutil.move(os.path.join(target, 'usr/local/Cg/docs/runtime/cgGL/txt'),
                '/usr/share/doc/nvidia-cg-toolkit/txt/cgGL')

    print "  examples,",
    shutil.move(os.path.join(target, 'usr/local/Cg/examples'),
                '/usr/share/doc/nvidia-cg-toolkit/examples')

    print "manual pages",
    for f in os.listdir(os.path.join(target, 'usr/share/man/man3')):
        src = os.path.join(target, 'usr/share/man/man3', f)
        dst = os.path.join('/usr/share/man/man3', f+'nvidiacg')
        shutil.move(src, dst)

    print "(compressing),",
    os.system('/bin/gzip -9 /usr/share/man/man3/*.3nvidiacg')

    shutil.rmtree(target)
    print "done."

def cg_wget():
    """Get toolkit archive from the network."""
    target = os.path.join('/tmp', 'cg.%f' % time.time())
    try:
        os.mkdir(target)
    except:
        e = "Error: can't create directory: %s."
        sys.stderr.write(e % target)
        sys.exit(2)
    dst = open(os.path.join(target, CG_FILE), 'w')

    print "Downloading NVIDIA Cg Toolkit to " + dst.name
    src = urllib2.urlopen(CG_URL+CG_FILE)
    dst.write(src.read())
    return dst.name

def cg_path(path, filename):
    """Return the path to an existing file or None."""
    if filename and os.path.exists(filename):
        return filename
    if path:
        filename = os.path.join(path, CG_FILE)
        if filename and os.path.exists(filename):
            return filename

    
parser = optparse.OptionParser(usage="%prog [options] <file or URL>")	
parser.add_option('-i', '--install', action='store_true',
                  help="install the NVIDIA Cg Toolkit")
parser.add_option('-u', '--uninstall', action='store_true',
                  help="uninstall the NVIDIA Cg Toolkit")
parser.add_option('-l', '--local-file', action='store',
                  help="install from given file")
parser.add_option('-s', '--search-path', action='store',
                  help="search for files in given path")
parser.add_option('-d', '--delete-after', action='store_true',
                  help="remove toolkit archive after install")
opts, args = parser.parse_args()


if opts.install:
    local_file = cg_path(opts.search_path, opts.local_file)
    if not local_file or not os.path.exists(local_file):
        local_file = cg_wget()
    cg_install(local_file)
    if opts.delete_after:
        os.unlink(local_file)

elif opts.uninstall:      
    cg_uninstall()

else:
    e = "Error: one action (--install or --uninstall) is required.\n"
    sys.stderr.write(e)
    sys.exit(1)
