#!/usr/bin/env python3
"""A script to set up COMMITTERS.rst according to gitlab committers."""

import os
import sys
import subprocess
import argparse
import json
import urllib.request
import urllib.parse
from jinja2 import Environment, FileSystemLoader
from collections import OrderedDict

GIT_ERROR = 1
MERGE_REQUEST = 'https://gitlab.com/api/v4/projects/1975139/merge_requests'
ALL_MEMBERS = 'https://gitlab.com/api/v4/projects/1975139/members/all'
PROTECTED = 'https://gitlab.com/api/v4/projects/1975139/protected_branches/master'
USERS = 'https://gitlab.com/api/v4/users/{}'
MAX_LEN = len('Full Name                         ')


def get_committers(token: str) -> OrderedDict:
    request = urllib.request.Request(PROTECTED)
    request.add_header('PRIVATE-TOKEN', token)
    response = urllib.request.urlopen(request).read().decode('utf-8')
    named_developers = [x['user_id'] for x in json.loads(response)['merge_access_levels']]
    request = urllib.request.Request(ALL_MEMBERS)
    request.add_header('PRIVATE-TOKEN', token)
    all_members = json.loads(urllib.request.urlopen(request).read().decode('utf-8'))
    names_usernames_dictionary = OrderedDict()
    for contributor in all_members:
        if contributor['access_level'] >= 40:
            names_usernames_dictionary[contributor['name']] = contributor['username']
    for contributor in named_developers:
        if contributor:
            request = urllib.request.Request(USERS.format(contributor))
            response = json.loads(urllib.request.urlopen(request).read().decode('utf-8'))
            if response['name'] != 'bst-marge-bot':
                names_usernames_dictionary[response['name']] = response['username']
    return names_usernames_dictionary


def get_table_entry(entry: str) -> str:
    res = entry
    for _ in range(MAX_LEN - len(entry)):
        res = res + ' '
    return res


def find_repository_root() -> str:
    root = os.getcwd()
    try:
        root = subprocess.check_output(['git', 'rev-parse', '--show-toplevel'])
    except subprocess.CalledProcessError as e:
        print('The current working directory is not a git repository. \
               \"git rev-parse --show-toplevel\" exited with code {}.'.format(e.returncode))
        sys.exit(GIT_ERROR)
    return root.rstrip().decode('utf-8')


def create_committers_file(committers: OrderedDict):
    repository_root = find_repository_root()
    contrib_directory = os.path.join(repository_root, 'contrib')
    file_loader = FileSystemLoader(contrib_directory)
    env = Environment(loader=file_loader, autoescape=True)
    template = env.get_template('COMMITTERS.rst.j2')
    render_output = template.render(committers=committers, get_table_entry=get_table_entry)
    committers_file = os.path.join(repository_root, 'COMMITTERS.rst')

    with open(committers_file, 'w') as f:
        f.write(render_output)


def commit_changes_if_needed(token: str):
    committers_file = os.path.join(find_repository_root(), 'COMMITTERS.rst')
    git_diff = subprocess.call(['git', 'diff', '--quiet', committers_file])
    if git_diff:
        commit_message = '\'Update COMMITTERS.rst\''
        branch_name = 'update_committers'
        subprocess.call(['git', 'add', committers_file])
        subprocess.call(['git', 'commit', '-m', commit_message])
        try:
            subprocess.check_call(['git', 'push', '-u', 'origin', branch_name], stderr=subprocess.STDOUT)
        except subprocess.CalledProcessError as e:
            print('Could not push to remote branch. \"git push -u origin {}\" \
                   exited with code {}.'.format(branch_name, e.returncode))
            sys.exit(GIT_ERROR)
        data = urllib.parse.urlencode({'source_branch': 'update_committers',
                                       'target_branch': 'master',
                                       'title': 'Update COMMITTERS.rst file'})
        request = urllib.request.Request(MERGE_REQUEST, data=bytearray(data, 'ASCII'))
        request.add_header('PRIVATE-TOKEN', token)
        response = urllib.request.urlopen(request)
        if response.getcode() != 200:
            print("Failed to open MR; please open an MR for branch {} manually".format(branch_name))


def main():
    parser = argparse.ArgumentParser(
        description="Update gitlab committers according to COMMITTERS.rst"
    )
    parser.add_argument(
        "token", type=str,
        help="Your private access token. See https://gitlab.com/profile/personal_access_tokens."
    )
    args = parser.parse_args()

    committers = get_committers(args.token)
    create_committers_file(committers)
    commit_changes_if_needed(args.token)


if __name__ == '__main__':
    main()
