#!/usr/bin/python

import argparse
import os
import grp
import pwd
import sys
import tempfile
from retrace import *

sys.path.insert(0, "/usr/share/retrace-server")
from plugins import *

TARGET_USER = "retrace"
TARGET_GROUP = "retrace"

if __name__ == "__main__":
    # parse arguments
    argparser = argparse.ArgumentParser(description="Retrace Server repository downloader")
    argparser.add_argument("distribution", type=str, help="Distribution name")
    argparser.add_argument("version", type=str, help="Release version")
    argparser.add_argument("architecture", type=str, help="CPU architecture")
    args = argparser.parse_args()

    distribution = args.distribution
    version = args.version
    arch = args.architecture

    if arch == "i686":
        arch = "i386"

    # drop privilegies if possible
    try:
        gr = grp.getgrnam(TARGET_GROUP)
        os.setgid(gr.gr_gid)
        pw = pwd.getpwnam(TARGET_USER)
        os.setuid(pw.pw_uid)
        print "Privileges set to '%s:%s'." % (TARGET_USER, TARGET_GROUP)
    except:
        print "Unable to change privileges to '%s:%s'. Exitting..." % (TARGET_USER, TARGET_GROUP)
        sys.exit(6)

    # load plugin
    plugin = None
    for iplugin in PLUGINS:
        if iplugin.distribution == distribution:
            plugin = iplugin
            break

    if not plugin:
        print "Unknown distribution: '%s'" % distribution
        sys.exit(1)

    targetid = "%s-%s-%s" % (distribution, version, arch)
    lockfile = "/tmp/retrace-reposync-lock-%s" % targetid

    if os.path.isfile(lockfile):
        print "Another process with repository download is running."
        sys.exit(2)

    # set lock
    if not lock(lockfile):
        print "Unable to set lock."
        sys.exit(3)

    null = open("/dev/null", "w")

    try:
        targetdir = os.path.join(CONFIG["RepoDir"], targetid)

        # run rsync
        for repo in plugin.repos:
            retcode = -1
            for mirror in repo:
                repourl = mirror.replace("$ARCH", arch).replace("$VER", version)

                print "Downloading packages from '%s'..." % repourl,
                sys.stdout.flush()

                if repourl.startswith("http://") or \
                   repourl.startswith("https://") or \
                   repourl.startswith("ftp://"):
                    yumtmp = tempfile.NamedTemporaryFile(mode="w", delete=False,
                                                         prefix="repo", suffix=".conf")
                    yumtmp.write("[%s]\n" % targetid)
                    yumtmp.write("name=%s\n" % targetid)
                    yumtmp.write("baseurl=%s\n" % repourl)
                    yumtmp.close()
                    retcode = call(["reposync", "--repoid=%s" % targetid,
                                    "--download_path=%s" % CONFIG["RepoDir"],
                                    "--config=%s" % yumtmp.name],
                                   stdout=null, stderr=null)

                    try:
                        os.unlink(yumtmp.name)
                    except Exception as ex:
                        print "Unable to unlink '%s': %s." % (yumtmp.name, ex)
                else:
                    if repourl.startswith("rsync://"):
                        files = [repourl]
                    else:
                        # folder in FS
                        files = []
                        try:
                            for package in os.listdir(repourl):
                                files.append(os.path.join(repourl, package))
                        except Exception as ex:
                            print "Error: %s. Trying another mirror..." % ex
                            continue

                    retcode = call(["rsync", "-t"] + files + [targetdir], stdout=null, stderr=null)

                if retcode == 0:
                    print "OK"
                    break

                print "Error. Trying another mirror..."

            if retcode != 0:
                print "No more mirrors to try."

        # run createrepo
        print "Running createrepo on '%s'..." % targetdir,
        sys.stdout.flush()

        cmd = ["createrepo", targetdir]
        if CONFIG["UseCreaterepoUpdate"]:
            cmd.append("--update")

        retcode = call(cmd, stdout=null, stderr=null)
    finally:
        null.close()
        unlock(lockfile)

    if retcode != 0:
        print "Failed"
        sys.exit(4)

    print "OK"
