#!/usr/bin/env python
# Copyright 2011 Red Hat Inc.
# Author: Kushal Das <kdas@redhat.com>
#
# 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 of the License, or (at your
# option) any later version.  See http://www.gnu.org/copyleft/gpl.html for
# the full text of the license.

import os
import sys
import stat
import MySQLdb
import tempfile
import subprocess
import ConfigParser
from optparse import OptionParser


def is_elf(filepath):
    """
    Finds if a file is elf or not
    """
    cmd = "file -k %s" % filepath
    data = system(cmd)
    data = data.split(": ")
    if len(data) > 1:
        if data[1].startswith('ELF'):
            return True
    return False


def find_elf_files(files):
    """
    Returns the ELF files from the list
    """
    elfs = []
    for filename in files:
        if os.path.exists(filename):
            if is_elf(filename):
                elfs.append(filename)
    return elfs

def removedir(path):
    """
    removes the dir which must be under /tmp and not a symlink
    """
    if os.path.islink(path):
        return
    if not path.startswith('/tmp'):
        return
    os.system('rm -rf %s' % path)



def system(cmd):
    """
    Invoke a shell command. Primary replacement for os.system calls.
    """
    ret = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE,
                stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True)
    out, err = ret.communicate()
    return out


def parserpm(path, config, distro="fedora"):
    """
    parse the rpm and insert data into database
    """
    filename = os.path.basename(path)

    try:
        #Find all db config
        dbhost = config.get('darkserver','host')
        dbuser =  config.get('darkserver','user')
        dbpassword = config.get('darkserver','password')
        dbname =  config.get('darkserver','database')
    except Exception, error:
        print "Please setup the database config file first at /etc/darkserver"
        return
    
    try:
        conn = MySQLdb.connect (host = dbhost,
                                user = dbuser,
                                passwd = dbpassword,
                                db = dbname)
    except Exception, error:
        print error.message
        return
    cursor = conn.cursor ()
    
    #Create the temp dir
    destdir = tempfile.mkdtemp(suffix='.' + str(os.getpid()), dir=None)

    #Extract the rpm
    cmd = 'rpmdev-extract -C %s %s' % (destdir, path)
    datum = system(cmd)
    data = datum.split('\n')
    
    #Find out all elf files from the list
    files = [os.path.join(destdir, row) for row in data]
    elffiles = find_elf_files(files)
    
    #Return if ELF file found in the RPM
    if not elffiles:
        return
    
    #Find the lenth of the destdir name
    dest_len = len(destdir)
    
    #run eu-unstrip and parse the result
    for eachfile in elffiles:
        data = system("eu-unstrip -n -e %s" % eachfile)
        try:
            name = eachfile[dest_len+1:]
            dirname = "/" + '/'.join(os.path.dirname(name).split('/')[1:])
            sql = "INSERT INTO dark_gnubuildid VALUES"\
                  " (null, '%s','%s','%s','%s','%s')"
            sql = sql % (os.path.basename(name), dirname, \
                         data.split(' ')[1].split('@')[0], \
                         filename[:-4], distro)

            cursor.execute(sql)
        except Exception, error:
            print error
    removedir(destdir)
    conn.commit()
    


def main(args):
    """
    Main function
    """
    parser = OptionParser()
    parser.add_option("-r", "--rpm", dest="rpm",
                          help="path to the rpm file")
    
    parser.add_option("-d", "--distro", dest="distro",
                          help="distro name")


    (options, args) = parser.parse_args(args)

    if not options.distro:
        print "Please provide a distro name"
        return -1

    if not options.rpm:
        print "Please provide path to the rpm"
        return -1
    
    if not os.path.isfile(options.rpm):
        print "Please provide path to the rpm"
        return -1
    
    #let us find the db configuration
    config = ConfigParser.ConfigParser()
    config.read('/etc/darkserver/darkserver.conf')
    
    parserpm(options.rpm, config, options.distro)


if __name__ == '__main__':
    main(sys.argv[1:])
