#!/usr/bin/python

# A script to convert a Pacman config file and mirrorlist into an
# Akabei config file and mirrorlist.
#
#   Copyright (C) 2011 Lisa Vitolo <shainer@chakraos.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 getopt

# A dictionary for translating the Pacman options.
# Those which map to an empty string aren't supported by Akabei, so they are deleted when found.
correspondences = {
                   "RootDir":"RootDir", "DBPath":"DatabaseDir", "CacheDir":"CacheDir",
                   "LogFile":"LogFile", "HoldPkg":"HoldPkg", "IgnorePkg":"IgnorePkg",
                   "SyncFirst":"SyncFirst", "IgnoreGroup":"IgnoreGroup", "Include":"Include",
                   "NoUpgrade":"NoUpgrade", "NoExtract":"NoExtract", "CleanMethod":"CleanMethod",
                   "UseSyslog":"UseSyslog", "ShowSize":"ShowSize", "TotalDownload":"TotalDownload",
                   "Server":"Server", "Include":"Include",
                   "Architecture":"", "XferCommand":"", "UseDelta":"", "ILoveCandy":""
                  }

def parseOptionLine(line, akabeiConf):
    separatedOption = line.partition('=')
    name = separatedOption[0]
    sep = separatedOption[1]
    value = separatedOption[2]

    nameNoSpace = name.rstrip()

    # Lines like [core] are copied verbatim
    if nameNoSpace.startswith("["):
        akabeiConf.write(name)
        return

    if nameNoSpace in correspondences:
        if len(correspondences[nameNoSpace]) > 0:

            # Replaces the option name with that used by Akabei and writes again the line
            name = name.replace(nameNoSpace, correspondences[nameNoSpace])
            akabeiConf.write(name)
            akabeiConf.write(sep)
            akabeiConf.write(value)
    # If it's not present in our dictionary, we assume it's a comment
    else:
        akabeiConf.write(name)
        akabeiConf.write(sep)
        akabeiConf.write(value)

# There is no format conversion to do here, we just copy the
# whole content.
def CopyMirrorlist(pacmanMirrorFile, akabeiMirrorFile):
    pacmanMirrors = ''

    with open(pacmanMirrorFile, 'r') as pm:
        pacmanMirrors = pm.read()

    with open(akabeiMirrorFile, 'w') as am:
        am.write(pacmanMirrors)


# Prints an help message
def usage():
    print("usage: " + sys.argv[0] + " [--help] [--pacman=<path to pacman.conf>] [--akabei=<path to akabei.conf>]")
    print
    print("Options:")
    print("    -h, --help                  Prints this help message")
    print("    -p, --pacman <file>         Reads pacman configuration from <file> (default: /etc/pacman.conf)")
    print("    -a, --akabei <file>         Writes akabei configuration in <file> (default: /etc/akabei.conf)")
    print("    -m, --pacman-mirrors <file> Reads pacman mirrorlist from <file> (default: /etc/pacman.d/mirrorlist)")
    print("    -n  --akabei-mirrors <file> Writes akabei mirrorlist to <file> (default: /etc/akabei.d/mirrorlist)")
    print("Note: if your destination paths already exists, they will be overwritten.")

# Start point
if __name__ == "__main__":
    # Default values for the commandline arguments.
    pacmanFile = "/etc/pacman.conf"
    akabeiFile = "/etc/akabei.conf"
    pacmanMirrorFile = "/etc/pacman.d/mirrorlist"
    akabeiMirrorFile = "/etc/akabei.d/mirrorlist"
    opts = None

    try:
        opts = getopt.getopt(
            sys.argv[1:], "hp:a:m:n:",
            ["help", "pacman=", "akabei=", "pacman-mirrors=", "akabei-mirrors="])
    except getopt.GetoptError as error:
        print(str(error))
        usage()
        sys.exit(-1)

    for opt, arg in opts[0]:
        if opt in ("-h", "--help"):
            usage()
            sys.exit(0)
        elif opt in ("-p", "--pacman"):
            pacmanFile = arg
        elif opt in ("-a", "--akabei"):
            akabeiFile = arg
        elif opt in ("-m", "--pacman-mirrors"):
            pacmanMirrorFile = arg
        elif opt in ("-n", "--akabei-mirrors"):
            akabeiMirrorFile = arg

    pacmanConf = None
    akabeiConf = None

    try:
        pacmanConf = open(pacmanFile, "r")
        akabeiConf = open(akabeiFile, "w")
    except IOError as error:
        print(str(error))
        sys.exit(-1)

    for pacmanLine in pacmanConf.readlines():

        if pacmanLine == "\n" or "[options]" in pacmanLine:
            akabeiConf.write("\n")
            continue

        pacmanLine = pacmanLine.replace("pacman", "akabei")

        # Skips the trailing whitespaces
        ch = 0
        while pacmanLine[ch] == ' ':
            ch += 1

        separatedLine = pacmanLine.partition('#')

        # These are all the normal lines in the form name=value
        parseOptionLine(separatedLine[0], akabeiConf)

        # The separator if present
        akabeiConf.write(separatedLine[1])

        # After the separator there could be some commented options.
        # If they're not supported by akabei or changed name
        # they are be deleted/modified to avoid confusion for the reader
        parseOptionLine(separatedLine[2], akabeiConf)

    print("[**] Your akabei configuration was created successfully.")
    pacmanConf.close()
    akabeiConf.close()

    CopyMirrorlist(pacmanMirrorFile, akabeiMirrorFile)
    print("[**] Your akabei mirrorlist was created successfully.")
