#!/usr/bin/env python

import jenkins
import optparse
import os
import sys
import urllib
import yaml

import jenkins_tools
from rosdistro import get_distribution_file, get_index, get_index_url, get_source_build_files
from rospkg import environment

ubuntu_distro = {'fuerte': ['precise'],
                 'groovy': ['precise'],
                 'hydro': ['precise']}
arch = ['amd64']


def build_job(jenkins_instance, job_name):
    #return jenkins_instance.build_job(job_name)
    # replicate internal implementation of Jenkins.build_job()
    import urllib2
    if not jenkins_instance.job_exists(job_name):
        raise jenkins.JenkinsException('no such job[%s]' % (job_name))
    # pass parameters to create a POST request instead of GET
    return jenkins_instance.jenkins_open(urllib2.Request(jenkins_instance.build_job_url(job_name), 'foo=bar'))


# Schedule all devel jobs on Jenkins
def main():
    parser = optparse.OptionParser()
    parser.add_option("--delete", action="store_true", default=False)
    parser.add_option("--run", action="store_true", default=False)
    (options, args) = parser.parse_args()

    if len(args) != 1:
        print "Usage: %s ros_distro" % (sys.argv[0])
        sys.exit(0)
    ros_distro = args[0]

    # create jenkins instance
    with open(os.path.join(environment.get_ros_home(), 'buildfarm', 'server.yaml')) as f:
        info = yaml.load(f)
    jenkins_instance = jenkins.Jenkins(jenkins_tools.JENKINS_SERVER, info['username'], info['password'])

    # parse the devel distro file
    print "Parsing devel yaml file for %s" % ros_distro
    if ros_distro != 'fuerte':
        index = get_index(get_index_url())
        distribution_file = get_distribution_file(index, ros_distro)
        source_repo_names = [repo_name for repo_name in distribution_file.repositories.keys() if distribution_file.repositories[repo_name].source_repository is not None]

        source_build_files = get_source_build_files(index, ros_distro)
        timeouts = []
        for source_build_file in source_build_files:
            repo_names = source_build_file.filter_repositories(source_repo_names)
            timeouts.append((repo_names, source_build_file.jenkins_job_timeout))

        devel = {}
        for repo_name in source_repo_names:
            repo = distribution_file.repositories[repo_name].source_repository
            repo_data = {
                'type': repo.type,
                'url': repo.url,
                'version': repo.version
            }
            # TODO only works with one build file yet
            repo_names, timeout = timeouts[0]
            if repo_name in repo_names and timeout:
                repo_data['timeout'] = timeout
            devel[repo_name] = repo_data
    else:
        f = urllib.urlopen('https://raw.github.com/ros/rosdistro/master/releases/%s-devel.yaml' % ros_distro)
        devel = yaml.load(f.read())['repositories']

    # create all jobs
    devel_jobs = []
    for s in sorted(devel.keys()):
        conf = devel[s]
        # replace forward slashes in repo names since they are not allowed in job names
        job_name = "devel-%s-%s" % (ros_distro, s.replace('/', '__'))
        if conf['type'] == 'svn':
            conf['version'] = ''
        if conf['version'] is None:
            print('- skip job "%s" because version is None' % job_name)
            continue
        jenkins_tools.run_jenkins_vcs(jenkins_instance, '$UBUNTU_PARAM', '$ARCH_PARAM',
                                      job_name, 'ros-buildfarm-devel@googlegroups.com',
                                      conf['type'], conf['url'], conf['version'],
                                      'devel', [ros_distro, s], info['username'],
                                      {'UBUNTU_PARAM': ['precise'], 'ARCH_PARAM': ['amd64']}, priority=60, timeout=conf.get('timeout'))
        devel_jobs.append(job_name)

    # run jobs right now
    if options.run:
        for d in devel_jobs:
            build_job(jenkins_instance, d)
            print "Started job %s" % d

    # delete old jobs
    if options.delete:
        remove = []
        current_jobs = [j['name'] for j in jenkins_instance.get_jobs()]
        for c in current_jobs:
            if 'devel-%s-' % ros_distro in c and not c in devel_jobs:
                remove.append(c)

        for r in remove:
            jenkins_instance.delete_job(r)
            print "Deleted old job %s" % r


if __name__ == "__main__":
    main()
