#!/usr/bin/python
import os
import re
import shutil
import sys
import time
from optparse import OptionParser


usage = "usage: %prog [options]\nUses pulp-admin against a list of repos to sync and/or export them to a specific directory. Use --help for a full list of options."
parser = OptionParser(usage=usage, description="")
parser.add_option("-v", "--verbose", action="store_true", dest="verbose", help="verbose mode")
parser.add_option("-s", "--sync", action="store_true", dest="sync",
                  help="Synchronize channels in file specified with --export-dir")
parser.add_option("-l", "--status", action="store_true", dest="status", help="obtain status")
parser.add_option("-r", "--repo-list", dest="repo_list",
                  help="File containing list of repositories to act on")
parser.add_option("-e", "--export-dir", dest="export_dir",
                  help="Directory to use as the disconnected synchronization store", metavar="DIRECTORY")
parser.add_option("-w", "--watch", action="store_true", dest="watch", help="Loop through every -t seconds watching status until CTRL+C is pressed.")
parser.add_option("-t", "--time-to-wait", default=10, dest="wait", 
                  help="Seconds to wait between status checks (default 10).")
parser.add_option("-f", "--force", action="store_true", dest="force",
                  help="Force overwrite of any existing exported directory.")


(options, args) = parser.parse_args()

opt_err = False
if not (options.sync or options.export_dir or options.status):
    print "error: One or more of the following are required: --sync, --export-dir, --status."
    opt_err = True
if options.sync and options.export_dir:
    options.watch = True
if not options.repo_list:
    print "error: --repo-list is required."
    opt_err = True
if opt_err:
    print usage
    sys.exit(1)

REPO_SYNC_STR = "pulp-admin repo sync --id %s"
REPO_SYNC_STATUS_STR = "pulp-admin repo status --id %s"
REPO_EXPORT_STR = "pulp-admin repo export --id %s --target_dir=%s"
REPO_EXPORT_STATUS_STR = "pulp-admin repo export --status --id %s"

# print verbose
def p_v(str):
    if options.verbose:
        print str

def sync_repos(repos):
    # loop through repos and request sync with each one
    try:
        for repo in repos:
            p_v("syncing repo %s" % repo)
            os.system(REPO_SYNC_STR % (repo))
    except KeyboardInterrupt:
        raise
    except:
        raise

def export_repos(repos, export_dir):
    # loop through repos and request export on each one
    try:
        for repo in repos:
            p_v("exporting repo %s"% repo)
            if options.force:
                os.system(REPO_EXPORT_STR % (repo, options.export_dir + repos[repo]) + " --overwrite")
            else:
                os.system(REPO_EXPORT_STR % (repo, options.export_dir + repos[repo]))
    except KeyboardInterrupt:
        raise
    except:
        raise

def status_repos(repos,type):
    # Loop through repos and request status on each one, different depending on if status or export
    try:
        for repo in repos:
            if type == "sync":
                p_v("statusing repo sync of: %s"% repo)
                os.system(REPO_SYNC_STATUS_STR % repo)
            elif type == "export":		
            # In the case that both export and sync are specified, only show sync status, otherwise it will attempt to show export status also which will fail untnil the sync is done and export has been initiated
                p_v("statusing repo export of: %s"% repo)
                os.system(REPO_EXPORT_STATUS_STR % repo)
    except KeyboardInterrupt:
        raise
    except:
        raise

def continuous_status_repos(repos,type):
    while True:
        p_v("continuous %s status loop starting" % type)
        try:
            status_repos(repos,type)
            print("=========================================================================")
            print(" Waiting %s seconds (press CTRL+C to cancel when all repos are %sed) " % (options.wait,type))
            print("=========================================================================")
            time.sleep(int(options.wait))
            os.system("clear")
        except KeyboardInterrupt:
            break
        except:
            raise

# main

f = open(options.repo_list, 'r+')
repo_list = f.readlines()
f.close()
repos = {}
for repo in repo_list:
    repo_name=repo.split('\t')[0]
    repo_dir=repo.split('\t')[1].strip()
    # Using a dictionary key as the repo name and the value is the dir
    repos[repo_name] = repo_dir
if options.sync:
    if not options.status:
        # Sync or watch requested
        sync_repos(repos)
    if options.watch:
        # Sync and export requested, or sync with --watch
        continuous_status_repos(repos,"sync")
    else:
        # Show sync status
        status_repos(repos,"sync")
if options.export_dir:
    if not options.status:
        # export or watch requested
        export_repos(repos, options.export_dir)
    if options.watch:
        # Sync and export requested or export with --watch
        continuous_status_repos(repos,"export")
    else:
        # Export status
        status_repos(repos,"export")
p_v("exiting")
print "\n"
