#!/usr/bin/env python3
# -*- coding: utf-8 -*-"
#
# Copyright 2020 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Module containing methods interfacing with gerrit.

i.e Create new bugfix change tickets, and reading metadata about a specific change.

Example CURL command that creates CL:
curl -b /home/chromeos_patches/.git-credential-cache/cookie \
        --header "Content-Type: application/json" \
        --data \
        '{"project":"chromiumos/third_party/kernel",\
        "subject":"test",\
        "branch":"chromeos-4.19",\
        "topic":"test_topic"}' https://chromium-review.googlesource.com/a/changes/
"""

from __future__ import print_function
import logging
import json
import http
import os
import re
import requests

import common
import git_interface


def get_auth_cookie():
    """Load cookies in order to authenticate requests with gerrit/googlesource."""
    # This cookie should exist in order to perform GAIA authenticated requests
    try:
        gerrit_credentials_cookies = \
                http.cookiejar.MozillaCookieJar(common.GCE_GIT_COOKIE_PATH, None, None)
        gerrit_credentials_cookies.load()
        return gerrit_credentials_cookies
    except FileNotFoundError:
        try:
            gerrit_credentials_cookies = \
                    http.cookiejar.MozillaCookieJar(common.LOCAL_GIT_COOKIE_PATH, None, None)
            gerrit_credentials_cookies.load()
            return gerrit_credentials_cookies
        except FileNotFoundError:
            logging.error('Could not locate gitcookies file. Generate cookie file and try again')
            logging.error('If running locally, ensure gitcookies file is located at ~/.gitcookies')
            logging.error('Learn more by visiting go/gob-dev#testing-user-authentication')
            raise


def retrieve_and_parse_endpoint(endpoint_url):
    """Retrieves Gerrit endpoint response and removes XSSI prefix )]}'"""
    try:
        resp = requests.get(endpoint_url, cookies=get_auth_cookie())
        resp.raise_for_status()
        resp_json = json.loads(resp.text[5:])
    except requests.exceptions.HTTPError as e:
        raise type(e)('Endpoint %s should have HTTP response 200' % endpoint_url) from e
    except json.decoder.JSONDecodeError as e:
        raise ValueError('Response should contain json )]} prefix to prevent XSSI attacks') from e

    return resp_json


def set_and_parse_endpoint(endpoint_url, payload=None):
    """POST request to gerrit endpoint with specified payload."""
    try:
        resp = requests.post(endpoint_url, json=payload, cookies=get_auth_cookie())
        resp.raise_for_status()
        resp_json = json.loads(resp.text[5:])
    except json.decoder.JSONDecodeError as e:
        raise ValueError('Response should contain json )]} prefix to prevent XSSI attacks') from e

    return resp_json


def get_full_changeid(changeid, branch):
    """Returns the changeid with url-encoding in project~branch~changeid format."""
    project = 'chromiumos%2Fthird_party%2Fkernel'
    chromeos_branch = common.chromeos_branch(branch)
    return '{project}~{branch}~{changeid}'.format(project=project,
                                                    branch=chromeos_branch,
                                                    changeid=changeid)


def get_reviewers(changeid, branch):
    """Retrieves list of reviewer emails from gerrit given a chromeos changeid."""
    unique_changeid = get_full_changeid(changeid, branch)
    list_reviewers_endpoint = os.path.join(common.CHROMIUM_REVIEW_BASEURL, 'changes',
                                        unique_changeid, 'reviewers')

    resp = retrieve_and_parse_endpoint(list_reviewers_endpoint)

    try:
        return [reviewer_resp['email'] for reviewer_resp in resp]
    except KeyError as e:
        raise type(e)('Gerrit API endpoint to list reviewers should contain key email') from e


def abandon_change(changeid, branch, reason=None):
    """Abandons a change."""
    unique_changeid = get_full_changeid(changeid, branch)
    abandon_change_endpoint = os.path.join(common.CHROMIUM_REVIEW_BASEURL, 'changes',
                                            unique_changeid, 'abandon')

    abandon_payload = {'message': reason} if reason else None

    try:
        set_and_parse_endpoint(abandon_change_endpoint, abandon_payload)
        logging.info('Abandoned changeid %s on Gerrit', changeid)
    except requests.exceptions.HTTPError as e:
        if e.response.status_code == http.HTTPStatus.CONFLICT:
            logging.info('Change %s has already been abandoned', changeid)
        else:
            raise


def restore_change(changeid, branch, reason=None):
    """Restores an abandoned change."""
    unique_changeid = get_full_changeid(changeid, branch)
    restore_change_endpoint = os.path.join(common.CHROMIUM_REVIEW_BASEURL, 'changes',
                                            unique_changeid, 'restore')

    restore_payload = {'message': reason} if reason else None

    try:
        set_and_parse_endpoint(restore_change_endpoint, restore_payload)
        logging.info('Restored changeid %s on Gerrit', changeid)
    except requests.exceptions.HTTPError as e:
        if e.response.status_code == http.HTTPStatus.CONFLICT:
            logging.info('Change %s has already been restored', changeid)
        else:
            raise


def get_change(changeid, branch):
    """Retrieves ChangeInfo from gerrit using its changeid"""
    unique_changeid = get_full_changeid(changeid, branch)
    get_change_endpoint = os.path.join(common.CHROMIUM_REVIEW_BASEURL, 'changes',
                                        unique_changeid)
    return retrieve_and_parse_endpoint(get_change_endpoint)


def set_hashtag(changeid, branch):
    """Set hashtag to be autogenerated indicating a robot generated CL."""
    unique_changeid = get_full_changeid(changeid, branch)
    set_hashtag_endpoint = os.path.join(common.CHROMIUM_REVIEW_BASEURL, 'changes',
                                        unique_changeid, 'hashtags')
    hashtag_input_payload = {'add' : ['autogenerated']}
    set_and_parse_endpoint(set_hashtag_endpoint, hashtag_input_payload)

def get_status(changeid, branch):
    """Retrieves the latest status of a changeid by checking gerrit."""
    change_info = get_change(changeid, branch)
    return change_info['status']

def get_bug_test_line(chrome_sha):
    """Retrieve BUG and TEST lines from the chrome sha."""
    # stable fixes don't have a fixee changeid
    bug_test_line = 'BUG=%s\nTEST=%s'
    bug = test = None
    if not chrome_sha:
        return bug_test_line % (bug, test)

    chrome_commit_msg = git_interface.get_chrome_commit_message(chrome_sha)

    bug_matches = re.findall('^BUG=(.*)$', chrome_commit_msg, re.M)
    test_matches = re.findall('^TEST=(.*)$', chrome_commit_msg, re.M)

    if bug_matches:
        bug = bug_matches[-1]
    if bug is None or bug == 'None':
        bug = 'None (see commit %s)' % chrome_sha
    if test_matches:
        test = test_matches[-1]

    return bug_test_line % (bug, test)


def generate_fix_message(fixer_upstream_sha, bug_test_line):
    """Generates new commit message for a fix change.

    Use script ./contrib/from_upstream.py to generate new commit msg
    Commit message should include essential information:
    i.e:
        FROMGIT, FROMLIST, ANDROID, CHROMIUM, etc.
        commit message indiciating what is happening
        BUG=...
        TEST=...
        tag for Fixes: <upstream-sha>
    """
    fix_upstream_commit_msg = git_interface.get_upstream_commit_message(fixer_upstream_sha)

    upstream_full_sha = git_interface.get_upstream_fullsha(fixer_upstream_sha)
    cherry_picked = '(cherry picked from commit %s)\n\n'% upstream_full_sha


    commit_message = ('UPSTREAM: {fix_commit_msg}'
                      '{cherry_picked}'
                      '{bug_test_line}').format(fix_commit_msg=fix_upstream_commit_msg,
                        cherry_picked=cherry_picked, bug_test_line=bug_test_line)

    return commit_message


# Note: Stable patches won't have a fixee_change_id since they come into chromeos as merges
def create_change(fixee_kernel_sha, fixer_upstream_sha, branch, fixer_changeid=None):
    """Creates a Patch in gerrit given a ChangeInput object.

    Determines whether a change for a fix has already been created,
    and avoids duplicate creations.
    """
    cwd = os.getcwd()
    chromeos_branch = common.chromeos_branch(branch)

    # fixee_changeid will be None for stable fixee_kernel_sha's
    fixee_changeid = git_interface.get_commit_changeid_linux_chrome(fixee_kernel_sha)

    # if fixee_changeid is set, the fixee_kernel_sha represents a chrome sha
    chrome_kernel_sha = fixee_kernel_sha if fixee_changeid else None

    bug_test_line = get_bug_test_line(chrome_kernel_sha)
    fix_commit_message = generate_fix_message(fixer_upstream_sha, bug_test_line)

    # TODO(hirthanan): find relevant mailing list/reviewers
    # For now we will assign it to a default user like Guenter?
    # This is for stable bug fix patches that don't have a direct fixee changeid
    #  since groups of stable commits get merged as one changeid
    reviewers = ['groeck@chromium.org']
    try:
        if fixee_changeid:
            cl_reviewers = get_reviewers(fixee_changeid, branch)
            if cl_reviewers:
                reviewers = cl_reviewers
    except requests.exceptions.HTTPError:
        # There is a Change-Id in the commit log, but Gerrit does not have a
        # matching entry. Fall back to list of e-mails found in tags after
        # the last "cherry picked" message.
        logging.warning('Failed to get reviewer(s) from gerrit for Change-Id %s', fixee_changeid)
        emails = git_interface.get_tag_emails_linux_chrome(fixee_kernel_sha)
        if emails:
            reviewers = emails

    try:
        # Cherry pick changes and generate commit message indicating fix from upstream
        fixer_changeid = git_interface.cherry_pick_and_push_fix(fixer_upstream_sha, fixer_changeid,
                                                    chromeos_branch, fix_commit_message, reviewers)
    except ValueError:
        # Error cherry-picking and pushing fix patch
        return None

    os.chdir(cwd)
    return fixer_changeid
