#!/usr/bin/python2 -s

"""
This script changes the directory path from the development tree to the
released tree once the release has been published.

In principle it should be run about a week after the said release has been
published.

This implies that for a week, users will be actually hitting the development
tree (which is hardlinked to the release tree and thus will have the same
content)
"""

import sys
import re
import os

sys.path.insert(0, os.path.join(os.path.dirname(
    os.path.abspath(__file__)), '..'))
import mirrormanager2.lib
from mirrormanager2.lib.model import RepositoryRedirect, Repository
from optparse import OptionParser

def fixup_repos(session, version, repo, new_dir):
    """ This functions has changed a lot since MM1. Now the given
    repository is updated to point to the right directory and the
    name is changed to reflect the new directory."""
    repo.name = new_dir.name
    repo.version = version
    repo.directory_id = new_dir.id
    session.add(repo)

    session.commit()


def move_devel_repo(session, category, version):
    c = mirrormanager2.lib.get_category_by_name(session, category)
    if c is None:
        print "Category '%s' not found, exiting" % category
        print_categories(session)
        sys.exit(1)

    v = mirrormanager2.lib.get_version_by_name_version(
        session, c.product.name, version)
    if not v:
        print 'Version %s not found for product %s' % (
            version, c.product.name)
        sys.exit(1)

    oldpattern = os.path.join('development', version)
    newpattern = os.path.join('releases', version)
    oldRe = re.compile(oldpattern)
    for r in c.repositories:
        if not r.prefix:
            # This script is only interested in repositories without
            # a prefix. Not changing existing repositories.
            continue
        d = r.directory
        if oldRe.search(d.name):
            t = d.name.replace(oldpattern, newpattern)
            new_d = mirrormanager2.lib.get_directory_by_name(session, t)
            if new_d is None:
                sys.stderr.write(
                    "target Directory(%s) not found, ignoring.\n" % t)
                sys.stderr.flush()
                continue

            if new_d.repositories:
                # The new directory already has a repository and will
                # thus lead to a duplicate key value violation.
                continue
            fixup_repos(session, v, r, new_d)
            print "%s => %s" % (d.name, t)

def print_categories(session):
    print "Available categories:"
    for c in mirrormanager2.lib.get_categories(session):
        print "\t%s" % c.name


def main():
    global options
    parser = OptionParser(
        usage=sys.argv[0] + " [options]")
    parser.add_option(
        "-c", "--config", dest="config",
        default='/etc/mirrormanager/mirrormanager2.cfg',
        help="Configuration file to use "
            "(default=/etc/mirrormanager/mirrormanager2.cfg)")
    parser.add_option(
        "--version", dest="version", type="string",
        help="OS version to move (e.g. '14') [required]", default=None)
    parser.add_option(
        "--category", dest="category", type="string",
        help="Category (e.g. 'Fedora Linux') [required]", default=None)

    (options, args) = parser.parse_args()

    d = dict()
    with open(options.config) as config_file:
        exec(compile(config_file.read(), options.config, 'exec'), d)

    session = mirrormanager2.lib.create_session(d['DB_URL'])

    if options.version is None or options.category is None:
        parser.print_help()
        print_categories(session)
        sys.exit(1)

    move_devel_repo(
        session,
        options.category,
        options.version)

    return 0


if __name__ == "__main__":
    sys.exit(main())
