#!/usr/bin/python

import re
import os
import sys
import posixpath

from subprocess import Popen, PIPE
from urlparse import urlparse

from optparse import OptionParser


DEFAULT_DIRECTORY = "/var/cache/checkbox/ltp"
DEFAULT_LOCATION = ":pserver:anonymous:@ltp.cvs.sourceforge.net:/cvsroot/ltp"
DEFAULT_TIMEOUT = 10800

COMMAND_TEMPLATE = "cd '%(directory)s' && ./runltp -f %(suite)s -r '%(directory)s' -p -q 2>/dev/null | ltp_filter --suite=%(suite)s"

def print_line(key, value):
    if type(value) is list:
        print "%s:" % key
        for v in value:
            print " %s" % v
    else:
        print "%s: %s" % (key, value)

def print_element(element):
    for key, value in element.iteritems():
        print_line(key, value)

    print

def parse_url(url):
    scheme, host, path, params, query, fragment = urlparse(url)

    if "@" in host:
        username, host = host.rsplit("@", 1)
        if ":" in username:
            username, password = username.split(":", 1)
        else:
            password = None
    else:
        username = password = None

    if ":" in host:
        host, port = host.split(":")
        assert port.isdigit()
        port = int(port)
    else:
        port = None

    return scheme, username, password, host, port, path, params, query, fragment

def checkout_ltp(location, directory):
    if posixpath.exists(directory):
        return

    target_directory = posixpath.basename(directory)
    next_directory = posixpath.dirname(directory)
    if not posixpath.exists(next_directory):
        os.makedirs(next_directory)

    previous_directory = posixpath.abspath(posixpath.curdir)
    os.chdir(next_directory)

    # Use this to prevent installing into /opt
    os.environ["DESTDIR"] = directory
    os.environ["SKIP_IDCHECK"] = "1"

    for command_template in [
            "cvs -d '%(location)s' login",
            "cvs -z3 -d '%(location)s' co -d %(target_directory)s ltp",
            "make -C '%(target_directory)s' autotools",
            "cd '%(target_directory)s' && ./configure",
            "make -C '%(target_directory)s'",
            "make -C '%(target_directory)s' install"]:
        command = command_template % {
            "location": location,
            "target_directory": target_directory}
        process = Popen(command, shell=True, stdout=PIPE, stderr=PIPE)
        stdout, stderr = process.communicate()
        if process.returncode:
            raise Exception, "Failed to run command %s" % command

    os.chdir(previous_directory)

def run_ltp(location, directory, timeout=None):
    checkout_ltp(location, directory)

    description_pattern = re.compile(r"#DESCRIPTION:(?P<description>.*)")

    elements = []
    directory = posixpath.join(directory, "opt", "ltp")
    suites_directory = posixpath.join(directory, "runtest")
    for suite_name in os.listdir(suites_directory):
        suite_path = posixpath.join(suites_directory, suite_name)
        if posixpath.isfile(suite_path):
            first_line = open(suite_path, "r").readline()
            match = description_pattern.match(first_line)
            if match:
                description = match.group("description")
                element = {}
                element["plugin"] = "remote"
                element["depends"] = "ltp"
                element["timeout"] = timeout
                element["name"] = suite_name
                element["description"] = match.group("description")
                element["user"] = "root"
                element["command"] = COMMAND_TEMPLATE % {
                    "suite": suite_name,
                    "directory":directory}

                elements.append(element)

    return elements

def main(args):
    usage = "Usage: %prog [OPTIONS]"
    parser = OptionParser(usage=usage)
    parser.add_option("-d", "--directory",
        default=DEFAULT_DIRECTORY,
        help="Directory where to branch ltp")
    parser.add_option("-l", "--location",
        default=DEFAULT_LOCATION,
        help="Location from where to checkout ltp")
    parser.add_option("-t", "--timeout",
        default=DEFAULT_TIMEOUT,
        type="int",
        help="Timeout when running ltp")
    (options, args) = parser.parse_args(args)

    # Check for http_proxy environment variable
    location = options.location
    if "http_proxy" in os.environ:
        host, port = parse_url(os.environ["http_proxy"])[3:5]
        pserver_proxy = "pserver;proxy=%s;proxyport=%s" % (host, port)
        location = location.replace("pserver", pserver_proxy)

    suites = run_ltp(location, options.directory, options.timeout)
    if not suites:
        return 1

    for suite in suites:
        print_element(suite)

    return 0


if __name__ == "__main__":
    sys.exit(main(sys.argv[1:]))
