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

# A script to convert the Pacman local database into an Akabei one
#
#   Copyright (C) 2011 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

from db_import import *
from akabeipackage import *
from akabeipackageparser import *
from akabeidbwriter import *
from akabeiprogressbar import *
    
# Each local package is represented in pacman as a directory in the form name-version
# in this path. This directory contains: desc, files (always), install (optional).
def parseLocalDatabase(path):
    """Parses a Pacman local database, found in |path|, and returns the packages
    as a list of AkabeiPackage objects."""
    desc = ""
    install = ""
    files = ""
    packages = []
    
    progress = 0.0
    progressReach100 = False
    
    # Since the number of packages will surely be more than 100,
    # we need to figure out what fraction we should make the progress bar advance
    # for each package parsed
    step = 1.0 / (len(os.listdir(path)) / 100)
    showProgress(progress)
    
    for pkgDir in os.listdir(path):
        pkgPath = os.path.join(path, pkgDir)
        
        if os.path.isdir(pkgPath):
            for pkgFile in os.listdir(pkgPath):
                if pkgFile == "desc":
                    desc = os.path.join(pkgPath, pkgFile)
                elif pkgFile == "install":
                    install = os.path.join(pkgPath, pkgFile)
                elif pkgFile == "files":
                    files = os.path.join(pkgPath, pkgFile)
            
            progress += step # update progress
            
            if progress == 100:
                progressReach100 = True
            
            # progress can surpass 100 by little quantities
            # this is seen when the progress bar reaching 100% but the cycle is still working on the last packages
            if progress <= 100:
                showProgress(progress)
            
            # Calls the package parser
            parser = PacmanPackageParser(desc, install, files)
            # Ignore packages that we could not parse successfully.
            if not parser.parsePackage():
                continue
            packages.append(parser.getPackage())
    
    # show last progress in case the progress never became exactly 100 (almost always)
    # If you remove the condition block, if progress reaches 100 then two bars will be displayed.
    if not progressReach100:
        showProgress(100)
        
    return packages
    
def usage():
    print "usage: " + sys.argv[0] + " [-h] [-p=<path to pacman.conf>] [-o=<akabei db file>] [-s=<akabei db scheme 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 "    -o, --db-output <file> Prints the Akabei database on <file> (default: local.db)"
    print "    -s, --db-scheme <file> Reads the database scheme from <file> (default: /usr/share/akabei/dbschema.sql)"

def DoConversion(pacmanConf, outputFile, schemeFile):
    """Entry point for converting the pacman db into an akabei one.
    Args:
      pacmanConf: path to pacman configuration
      outputFile: path of the output database.
      schemeFile: path of the SQLite scheme file for the Akabei database.
    """
    # Gets the database path from the pacman configuration
    print "[**] Reading Pacman database path from " + pacmanConf + "...",
    dbpath = getDatabasePath(pacmanConf)
    print "done."
    if len(dbpath) == 0:
        dbpath = "/var/lib/pacman" # if not explicitly set there, then go back to the default value
    
    localPath = os.path.join(dbpath, "local")
    
    # Get local packages from pacman, then write them into the akabei database in the right format
    
    print "[**] Parsing Pacman local database from %s..." % localPath
    localPackages = parseLocalDatabase(localPath)
    print "done."
    
    dbwriter = AkabeiDbWriter(outputFile, schemeFile)
    dbwriter.addPackages(localPackages)
    
    print "[**] Database converted successfully. Now enjoy akabei!"

# Start here.
if __name__ == "__main__":
    
    # Default values for files
    pacmanConf = "/etc/pacman.conf"
    outputFile = "local.db"
    schemeFile = "/usr/share/akabei/dbschema.sql"
    opts = None
    
    # Reads options from command line
    try:
        opts = getopt.getopt(sys.argv[1:], "hp:o:s:", ["help", "--pacman=" "--db-output=", "--db-scheme="])
    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 len(arg) > 0 and arg[0] == '=':
            arg = arg[1:]
        
        if opt in ("-h", "--help"):
            usage()
            sys.exit(0)
        elif opt in ("-p", "--pacman"):
            pacmanConf = arg
        elif opt in ("-o", "--db-output"):
            outputFile = arg
        elif opt in ("-s", "--db-scheme"):
            schemeFile = arg
            
    print "==== Akabei database conversion script v0.1 ==== "
    print "This script may take some time to finish."
    print
   
    DoConversion(pacmanConf, outputFile, schemeFile)
