#!/usr/bin/env python
#
# This file is part of REPA: Release Engineering Process Assistant.
#
# Copyright (C) 2013 Intel Corporation
#
# REPA is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# version 2 as published by the Free Software Foundation.
#
# 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., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.

"""
REPA: Release Engineering Process Assistant.

Copyright (C) Intel Corporation 2013
Licence: GPL version 2
Author: Ed Bartosh <eduard.bartosh@intel.com>

List module.
Get list of submissions.
"""

import sys
import json

from repa.common import (OBS_PROJECT_PREFIX, Colorizer,
                         get_download_url, get_obs_url)
from repa.obs import OBS
from repa.main import sub_main

def get_status(meta, colorizer, build_results=None):
    """Get overall status by analyzing package and image build status."""
    if build_results:
        codes = set()
        for target in build_results.itervalues():
            codes.add(target.get('code'))
            codes.add(target.get('state'))
            for pkginfo in target['packages']:
                codes.add(pkginfo[1])

        statuses = [('broken', ('red', 'broken source')),
                    ('unresolvable', ('red', 'unresolvable packages')),
                    ('failed', ('red', 'package build failed')),
                    ('building', ('blue', 'package building')),
                    ('blocked', ('blue', 'blocked'))]
        for pkgstatus, (color, status) in statuses:
            if pkgstatus in codes:
                return getattr(colorizer, color)(status)

    if 'images' in meta:
        for img in meta['images']:
            statuses = [('failed', ('red', 'image build failed')),
                        ('building', ('blue', 'image building'))]
            for imgstatus, (color, status) in statuses:
                if img['status'] == imgstatus:
                    return getattr(colorizer, color)(status)
    else:
        return colorizer.blue('waiting for images')

    return colorizer.green('ready')


def show_urls(meta):
    """Print OBS and download urls."""
    download_url = get_download_url(meta)
    if download_url:
        print '    download url: ', download_url
    obs_url = get_obs_url(meta)
    if obs_url:
        print '    obs url: ', obs_url
    print


def list_submissions(obs, target, processes, is_colorize=False,
                     showurls=False):
    """List submissions and groups."""
    colorizer = Colorizer(is_colorize)
    # submissions
    groups = []
    for project, desc, build_results in \
                obs.get_projects('^%s%s:submit' % (OBS_PROJECT_PREFIX, target),
                                 processes):
        meta = json.loads(desc)
        if ':submitgroup:' in project:
            groups.append(meta)
            continue
        projects = [project.split('/')[-1] for project in meta['projects']]
        print '%-37s %-37s %s' % (meta['git_tag'], \
              get_status(meta, colorizer, build_results), ','.join(projects))
        if showurls:
            show_urls(meta)

    # groups
    if groups:
        print
        for meta in groups:
            print '%-37s %-37s' % (meta['name'], get_status(meta, colorizer))
            if showurls:
                show_urls(meta)


class List(object):
    """Subcommand: List submissions."""

    name = 'list'
    description = 'List submissions'
    help = description

    @staticmethod
    def add_arguments(parser, config):
        """
        Add arguments to the parser. Called from [sub_]main.
        Set defaults for arguments from config.
        """
        parser.add_argument('--processes', type=int,
                            help='amount of parallel processes to use',
                            default=config.get('processes'))
        parser.add_argument('--showurls', action='store_true',
                            help='show OBS and download urls',
                            default=config.get('showurls', '').lower() == 'on')

    @staticmethod
    def run(argv):
        """Command line entry point. Called from [sub_]main"""
        obs = OBS(argv.apiurl, argv.apiuser, argv.apipasswd)
        return list_submissions(obs, argv.project, argv.processes,
                                argv.colorize, argv.showurls)


if __name__ == '__main__':
    sys.exit(sub_main(sys.argv[1:], List()))
