#!/usr/bin/env python
# vim: ai ts=4 sts=4 et sw=4
#
# Copyright (C) 2010, 2011, 2012, 2013, 2014 Intel, Inc.
#
#    This program is free software; you can redistribute it and/or
#    modify it under the terms of the GNU General Public License
#    as published by the Free Software Foundation; version 2
#    of the License.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
"""
This code run the rsync job immediately if no running builds exists.
"""

import os
import sys
import json
import base64
from urllib import quote_plus

from common.buildtrigger import trigger_info, trigger_next, get_pending_builds_with_parameter, get_running_builds_with_parameter, remote_jenkins_build_job, cancel_pending_build_with_id

JOB_NAME = 'rsync_download'

def pending_build_exists(job_name):

    pending_builds = []

    pending_build_queue = get_pending_builds_with_parameter()
    if not pending_build_queue:
        print 'No pending builds'
        return pending_builds
    for _queue in pending_build_queue:
        if 'task' not in _queue or 'name' not in _queue.get('task') \
            or job_name != _queue.get('task').get('name'):
            continue
        for action in _queue.get('actions'):
            if not 'parameters' in action:
                continue
            for param in action.get('parameters'):
                name = param.get('name')
                value = param.get('value')
                if name == 'TRIGGER_INFO' and value:
                    pending_info = trigger_info(value, show=False)
                    pending_builds.append({_queue.get('id'): pending_info})

    return pending_builds

def running_build_exists(job_name):

    running_builds = []

    running_build_jobs = get_running_builds_with_parameter(job_name)
    if not running_build_jobs:
        print 'No running builds'
        return running_builds
    for _run in running_build_jobs.get('builds'):
        if _run.get('building', False) == False:
            continue
        for action in _run.get('actions'):
            if not 'parameters' in action:
                continue
            for param in action.get('parameters'):
                name = param.get('name')
                value = param.get('value')
                if name == 'TRIGGER_INFO' and value:
                    running_info = trigger_info(value, show=False)
                    running_builds.append({_run.get('queueId'): running_info})

    return running_builds

def find_trigger_info(pool, queue_id):

    for x in pool:
        qid = x.keys()[0]
        if queue_id == qid:
            return x[queue_id]

    #raise False
    return None

def main():
    """Script entry point.
       Parameters:
          action - cleanup or create_images
    """

    num_max_concurrent = 4

    project_map = {}

    pending_builds = pending_build_exists(JOB_NAME)

    if not pending_builds or pending_builds is None or len(pending_builds) == 0:
        return

    running_builds = running_build_exists(JOB_NAME)

    if running_builds and len(running_builds) >= num_max_concurrent:
        print 'Maximum concurrent reached %d' % len(running_builds)
        return

    for x in pending_builds:
        queue_id = x.keys()[0]
        project = x[queue_id].get('project')
        if not project in project_map:
            project_map[project] = {'queue': [], 'build': []}
        project_map[project].get('queue').append(queue_id)

    for x in running_builds:
        queue_id = x.keys()[0]
        project = x[queue_id].get('project')
        if not project in project_map:
            project_map[project] = {'queue': [], 'build': []}
        project_map[project].get('build').append(queue_id)

    sys.stdout.flush()

    num_new_assigned = 0
    for x in project_map:
        project = x
        queue_list = project_map[project].get('queue')
        print queue_list
        build_list = project_map[project].get('build')
        if build_list is None or len(build_list) == 0 \
            and queue_list and len(queue_list) > 0:
            queue_id = sorted(queue_list)[0]
            ti = find_trigger_info(pending_builds, queue_id)
            encoded_data = base64.b64encode(json.dumps(ti))
            print '\n********'
            print '  Lets cancel %s(%d) and re-trigger\n  [%s]' \
                % (project, queue_id, encoded_data) 
            sys.stdout.flush()
            cancel_pending_build_with_id(queue_id)
            remote_jenkins_build_job(os.getenv('JENKINS_URL_INTERNAL'), \
                                     os.getenv('JENKINS_USER'), \
                                     os.getenv('JENKINS_PW'), \
                                     jobname=JOB_NAME, \
                                     data='TRIGGER_INFO="%s"&delay=0' % (quote_plus(encoded_data)))
            num_new_assigned += 1
            if ( num_new_assigned + len(running_builds) ) >= num_max_concurrent:
                print 'Slots reached Full!'
                break
        else:
            print '\n********'
            print '  Still running %s(%d)' \
                % (project, queue_id)

    print '\n"TitleDisplay": "%d"\n' % num_new_assigned

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


