#!/usr/bin/env python

import argparse
import os
import shutil
import subprocess
import sys


CACHEDIR = "/var/cache/ansible/ansible.checkout.clean"
CORECACHEDIR = "/var/cache/ansible/ansible-modules-core.checkout.clean"
EXTRASCACHEDIR = "/var/cache/ansible/ansible-modules-extras.checkout.clean"
BASEDIR = "/var/cache/ansible/version_checkouts"


def run_command(args, verbose):
    if verbose:
        print('Cmd: {}'.format(args))
    p = subprocess.Popen(
        args,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        shell=True
    )
    (so, se) = p.communicate()
    if verbose:
        print('rc: {}'.format(p.returncode))
        print('stdout: {}'.format(so))
        print('stderr: {}'.format(se))
    return (p.returncode, so, se)


def get_clean_cache(verbose=False):

    current_dir = os.path.abspath(os.curdir)

    if not os.path.isdir(CACHEDIR):
        run_command('git clone https://github.com/ansible/ansible.git'
                    ' --recursive {0}'.format(CACHEDIR), verbose)
    else:
        os.chdir(CACHEDIR)
        run_command('git pull --rebase --recurse-submodules', verbose)
        run_command('git submodule update --recursive', verbose)

    if not os.path.isdir(CORECACHEDIR):
        run_command('git clone https://github.com/ansible/ansible-modules-core.git'
                    ' --recursive {0}'.format(CORECACHEDIR), verbose)
    else:
        os.chdir(CORECACHEDIR)
        run_command('git pull --rebase --recurse-submodules', verbose)
        run_command('git submodule update --recursive', verbose)

    if not os.path.isdir(EXTRASCACHEDIR):
        run_command('git clone https://github.com/ansible/ansible-modules-extras.git'
                    ' --recursive {0}'.format(EXTRASCACHEDIR), verbose)
    else:
        os.chdir(EXTRASCACHEDIR)
        run_command('git pull --rebase --recurse-submodules', verbose)
        run_command('git submodule update --recursive', verbose)

    os.chdir(current_dir)


def main():

    global CACHEDIR
    global CORECACHEDIR
    global EXTRASCACHEDIR
    global BASEDIR

    (rc, so, se) = run_command('ansible-tools-cachedir', False)
    if isinstance(so, bytes):
        so = so.decode('utf-8')
    cachedir = so.strip()
    CACHEDIR = os.path.join(cachedir, "ansible.checkout.clean")
    CORECACHEDIR = os.path.join(cachedir, "ansible-modules-core.checkout.clean")
    EXTRASCACHEDIR = os.path.join(cachedir, "ansible-modules-extras.checkout.clean")
    BASEDIR = os.path.join(cachedir, "version_checkouts")

    parser = argparse.ArgumentParser()
    parser.add_argument('-v', '--verbose', action='store_true')
    args = parser.parse_args()

    if not os.path.isdir(BASEDIR):
        os.makedirs(BASEDIR)

    get_clean_cache(args.verbose)

    (rc, so, se) = run_command('ansible-list-versions', args.verbose)
    try:
        lines = so.split('\n')
    except TypeError:
        lines = so.decode('utf-8').split('\n')
    VERSIONS = [x.strip() for x in lines
                if x.strip() and 'devel' not in x]

    for V in VERSIONS:
        if args.verbose:
            print('#####################################################')
            print('process %s checkout' % V)
        dstdir = os.path.join(BASEDIR, 'ansible.%s' % V)
        if not os.path.isdir(dstdir):
            #shutil.copytree(CACHEDIR,dstdir)
            cmd = 'cp -Rp {} {}'.format(CACHEDIR, dstdir)
            (rc, so, se) = run_command(cmd, args.verbose)
            if rc != 0:
                print('ERROR: {}'.format(str(so) + str(se)))
                sys.exit(rc)
        else:
            # skip existing checkouts
            continue

        cmd = 'cd %s; git checkout -f tags/%s' % (dstdir, V)
        (rc, so, se) = run_command(cmd, args.verbose)

        # any submodules?
        gmfile = os.path.join(dstdir, '.gitmodules')
        if os.path.isfile(gmfile):
            coredir = os.path.join(dstdir, 'lib/ansible/modules/core')
            if not os.path.isdir(coredir):
                continue
            sysdir = os.path.join(coredir, 'system')
            if os.path.isdir(sysdir):
                continue
            #import epdb; epdb.st()
            cmd = 'cd {}; cp -Rp {}/* {}/.git* {}/'.format(dstdir, CORECACHEDIR, CORECACHEDIR, 'lib/ansible/modules/core')
            (rc, so, se) = run_command(cmd, args.verbose)

            cmd = 'cd {}; cp -Rp {}/* {}/.git* {}/'.format(dstdir, EXTRASCACHEDIR, EXTRASCACHEDIR, 'lib/ansible/modules/extras')
            (rc, so, se) = run_command(cmd, args.verbose)

            with open(gmfile) as gitmodule_file:
                gitmodule_data = gitmodule_file.read()
                if '[submodule "v2' in gitmodule_data:
                    cmd = 'cd {}; cp -Rp {}/* {}/.git* {}/'.format(dstdir, CORECACHEDIR, CORECACHEDIR, 'v2/ansible/modules/core')
                    (rc, so, se) = run_command(cmd, args.verbose)

                    cmd = 'cd {}; cp -Rp {}/* {}/.git* {}/'.format(dstdir, EXTRASCACHEDIR, EXTRASCACHEDIR, 'v2/ansible/modules/extras')
                    (rc, so, se) = run_command(cmd, args.verbose)


            cmd = 'cd %s; git submodule absorbgitdirs' % dstdir
            (rc, so, se) = run_command(cmd, args.verbose)

            cmd = 'cd %s; git submodule update --init --recursive' % dstdir
            (rc, so, se) = run_command(cmd, args.verbose)


if __name__ == "__main__":
    main()
