#!/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=('Wether 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()
