#!/usr/bin/python
# -*- coding: utf8 -*-

# A script to test the database conversion
# TODO: add more testing
#
#   Copyright (C) 2012 Lisa Vitolo <shainer@chakra-project.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 of the License, or (at your option) any later version.

import sys
import os
import getopt

try:
    from pysqlite2 import dbapi2 as sqlite
except ImportError:
    print "[!!] You need to install the python-pysqlite package to execute this script. Quitting..."
    sys.exit(-1)

# Reads the package name directly from the main information file
# This is much safer than obtaining it from the directory name for cause of
# inconsistencies in version specifications
def getPackageName(pkgDir):
    descFile = open(os.path.join(pkgDir, "desc"), "r")
    isName = False
    
    for line in descFile.readlines():
        line = line[:-1]
        
        # Tag for the package name
        if line == "%NAME%":
            isName = True
            continue
        
        if isName and len(line) > 0:
            descFile.close()
            return line
        
    descFile.close()
    return ""

def compareDatabases(pacmanDb, akabeiDb):
    
    # Test the presence and reading permissions of the akabei database file
    # before opening a connection with the sqlite module
    try:
        db = open(akabeiDb, "r")
        db.close()
    except IOError, error:
        print str(error)
        print "[!!] Error opening the Akabei local database for reading. Quitting..."
        sys.exit(-1)
    
    dbconnection = sqlite.connect(akabeiDb)
    dbconnection.text_factory = str # needed for some fields
    dbcursor = dbconnection.cursor()

    # Takes every package in the pacman database directory and looks for it in the akabei database
    for pkgDir in os.listdir(pacmanDb):
        if not os.path.isdir(pkgDir):
            continue

        pkgname = getPackageName(os.path.join(pacmanDb, pkgDir))
        
        query = "SELECT * FROM packages WHERE name='" + pkgname + "'"
        dbcursor.execute(query)
        
        if len(dbcursor.fetchall()) == 0: # lines from result
            return pkgname # package that didn't match
            
    return "" # all good!

# Try to read the DBPath config line from pacman.conf
# to see if the user set a different value from the default one
def getDatabasePath(pf):
    try:
        conf = open(pf, "r")
    except IOError, err:
        print str(err)
        print "[!!] This script needs your pacman config file to perform the conversion."
        print "[!!] Use " + sys.argv[0] + " -p <path to your pacman.conf> to specify a different configuration file."
        sys.exit(-1)
    
    for pacmanLine in conf.readlines():
        separatedLine = pacmanLine.partition("=")
        
        optname = separatedLine[0]
        
        # Deletes trailing whitespaces on both sides
        optname = optname.lstrip()
        optname = optname.rstrip()
        
        if (optname == "DBPath"):
            optvalue = separatedLine[2].partition("#")[0] # leaves out comments after the db path
            optvalue = optvalue.lstrip()
            optvalue = optvalue.rstrip()
            
            conf.close()
            return optvalue
    
    conf.close()
    return ""

def usage():
    print "usage: " + sys.argv[0] + " [-h] [-p=<path to pacman.conf>] [-d=<akabei db file>]"
    print
    print "Options:"
    print "    -h, --help             Prints this help message"
    print "    -p, --pacman <file>    Reads pacman configuration from <file> (default: /etc/pacman.conf)"
    print "    -d, --db-file <file> Prints the Akabei database on <file> (default: local.db)"

# Start point
if __name__ == "__main__":
    pacmanConf = "/etc/pacman.conf"
    dbFile = "local.db"
    opts = None
    
    # Reads options from command line
    try:
        opts = getopt.getopt(sys.argv[1:], "hp:d:", ["help", "--pacman=" "--db-file="])
    except getopt.GetoptError, error:
        print str(error)
        usage()
        sys.exit(-1)
    
    # Parse options and overrides defaults if needed
    for opt, arg in opts[0]:
        if opt in ("-h", "--help"):
            usage()
            sys.exit(0)
        elif opt in ("-p", "--pacman"):
            pacmanConf = arg
        elif opt in ("-d", "--db-file"):
            dbFile = arg
    
    print "[**] Reading Pacman database path from " + pacmanConf + "...",
    dbpath = getDatabasePath(pacmanConf)
    print "done."
    if len(dbpath) == 0:
        dbpath = "/var/lib/pacman/local" # if not explicitly set there, then go back to the default value
    
    print "[**] Comparing databases ..."
    diff = compareDatabases(dbpath, dbFile)
    
    if len(diff) > 0:
        print "[!!] Package " + diff + " was found in pacman db but not in akabei db"
    else:
        print "[**] Test passed."
