#!/usr/bin/env python3
#
# Copyright (c) 2019-2020 Red Hat, Inc.
#
# Author:
#  Cleber Rosa <crosa@redhat.com>
#
# This work is licensed under the terms of the GNU GPL, version 2 or
# later.  See the COPYING file in the top-level directory.

"""
Checks the GitLab pipeline status for a given commit ID
"""

# pylint: disable=C0103

import argparse
import http.client
import json
import os
import subprocess
import time
import sys


class CommunicationFailure(Exception):
    """Failed to communicate to gitlab.com APIs."""


class NoPipelineFound(Exception):
    """Communication is successful but pipeline is not found."""


def get_local_branch_commit(branch):
    """
    Returns the commit sha1 for the *local* branch named "staging"
    """
    result = subprocess.run(['git', 'rev-parse', branch],
                            stdin=subprocess.DEVNULL,
                            stdout=subprocess.PIPE,
                            stderr=subprocess.DEVNULL,
                            cwd=os.path.dirname(__file__),
                            universal_newlines=True).stdout.strip()
    if result == branch:
        raise ValueError("There's no local branch named '%s'" % branch)
    if len(result) != 40:
        raise ValueError("Branch '%s' HEAD doesn't look like a sha1" % branch)
    return result


def get_json_http_response(url):
    """
    Returns the JSON content of an HTTP GET request to gitlab.com
    """
    connection = http.client.HTTPSConnection('gitlab.com')
    connection.request('GET', url=url)
    response = connection.getresponse()
    if response.code != http.HTTPStatus.OK:
        msg = "Received unsuccessful response: %s (%s)" % (response.code,
                                                           response.reason)
        raise CommunicationFailure(msg)
    return json.loads(response.read())


def get_pipeline_status(project_id, commit_sha1):
    """
    Returns the JSON content of the pipeline status API response
    """
    url = '/api/v4/projects/{}/pipelines?sha={}'.format(project_id,
                                                        commit_sha1)
    json_response = get_json_http_response(url)

    # As far as I can tell, there should be only one pipeline for the same
    # project + commit. If this assumption is false, we can add further
    # filters to the url, such as username, and order_by.
    if not json_response:
        msg = "No pipeline found for project %s and commit %s" % (project_id,
                                                                  commit_sha1)
        raise NoPipelineFound(msg)
    return json_response[0]


def wait_on_pipeline_success(timeout, interval,
                             project_id, commit_sha):
    """
    Waits for the pipeline to finish within the given timeout
    """
    start = time.time()
    while True:
        if time.time() >= (start + timeout):
            msg = ("Timeout (-t/--timeout) of %i seconds reached, "
                   "won't wait any longer for the pipeline to complete")
            msg %= timeout
            print(msg)
            return False

        try:
            status = get_pipeline_status(project_id, commit_sha)
        except NoPipelineFound:
            print('Pipeline has not been found, it may not have been created yet.')
            time.sleep(1)
            continue

        pipeline_status = status['status']
        status_to_wait = ('created', 'waiting_for_resource', 'preparing',
                          'pending', 'running')
        if pipeline_status in status_to_wait:
            print('%s...' % pipeline_status)
            time.sleep(interval)
            continue

        if pipeline_status == 'success':
            return True

        msg = "Pipeline failed, check: %s" % status['web_url']
        print(msg)
        return False


def create_parser():
    parser = argparse.ArgumentParser(
        prog='pipeline-status',
        description='check or wait on a pipeline status')

    parser.add_argument('-t', '--timeout', type=int, default=7200,
                        help=('Amount of time (in seconds) to wait for the '
                              'pipeline to complete.  Defaults to '
                              '%(default)s'))
    parser.add_argument('-i', '--interval', type=int, default=60,
                        help=('Amount of time (in seconds) to wait between '
                              'checks of the pipeline status.  Defaults '
                              'to %(default)s'))
    parser.add_argument('-w', '--wait', action='store_true', default=False,
                        help=('Whether to wait, instead of checking only once '
                              'the status of a pipeline'))
    parser.add_argument('-p', '--project-id', type=int, default=11167699,
                        help=('The GitLab project ID. Defaults to the project '
                              'for https://gitlab.com/qemu-project/qemu, that '
                              'is, "%(default)s"'))
    parser.add_argument('-b', '--branch', type=str, default="staging",
                        help=('Specify the branch to check. '
                              'Use HEAD for your current branch. '
                              'Otherwise looks at "%(default)s"'))
    parser.add_argument('-c', '--commit',
                        default=None,
                        help=('Look for a pipeline associated with the given '
                              'commit.  If one is not explicitly given, the '
                              'commit associated with the default branch '
                              'is used.'))
    parser.add_argument('--verbose', action='store_true', default=False,
                        help=('A minimal verbosity level that prints the '
                              'overall result of the check/wait'))
    return parser

def main():
    """
    Script entry point
    """
    parser = create_parser()
    args = parser.parse_args()

    if not args.commit:
        args.commit = get_local_branch_commit(args.branch)

    success = False
    try:
        if args.wait:
            success = wait_on_pipeline_success(
                args.timeout,
                args.interval,
                args.project_id,
                args.commit)
        else:
            status = get_pipeline_status(args.project_id,
                                         args.commit)
            success = status['status'] == 'success'
    except Exception as error:      # pylint: disable=W0703
        if args.verbose:
            print("ERROR: %s" % error.args[0])
    except KeyboardInterrupt:
        if args.verbose:
            print("Exiting on user's request")

    if success:
        if args.verbose:
            print('success')
        sys.exit(0)
    else:
        if args.verbose:
            print('failure')
        sys.exit(1)


if __name__ == '__main__':
    main()
