#!/usr/bin/env python
# Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
#
# Use of this source code is governed by a BSD-style license
# that can be found in the LICENSE file in the root of the source
# tree. An additional intellectual property rights grant can be found
# in the file PATENTS.  All contributing project authors may
# be found in the AUTHORS file in the root of the source tree.

"""Script to auto-update the WebRTC source version in call/version.cc"""

import argparse
import datetime
import logging
import os
import re
import subprocess
import sys


def FindSrcDirPath():
    """Returns the abs path to the src/ dir of the project."""
    src_dir = os.path.dirname(os.path.abspath(__file__))
    while os.path.basename(src_dir) != 'src':
        src_dir = os.path.normpath(os.path.join(src_dir, os.pardir))
    return src_dir


UPDATE_BRANCH_NAME = 'webrtc_version_update'
CHECKOUT_SRC_DIR = FindSrcDirPath()


def _RemovePreviousUpdateBranch():
    active_branch, branches = _GetBranches()
    if active_branch == UPDATE_BRANCH_NAME:
        active_branch = 'master'
    if UPDATE_BRANCH_NAME in branches:
        logging.info('Removing previous update branch (%s)',
                     UPDATE_BRANCH_NAME)
        subprocess.check_call(['git', 'checkout', active_branch])
        subprocess.check_call(['git', 'branch', '-D', UPDATE_BRANCH_NAME])
    logging.info('No branch to remove')


def _GetLastAuthor():
    """Returns a string with the author of the last commit."""
    author = subprocess.check_output(['git', 'log',
                                      '-1',
                                      '--pretty=format:"%an"']).splitlines()
    return author


def _GetBranches():
    """Returns a tuple (active, branches).

    'active' is a string with name of the currently active branch, while
     'branches' is the list of all branches.
    """
    lines = subprocess.check_output(['git', 'branch']).splitlines()
    branches = []
    active = ''
    for line in lines:
        if '*' in line:
            # The assumption is that the first char will always be the '*'.
            active = line[1:].strip()
            branches.append(active)
        else:
            branch = line.strip()
            if branch:
                branches.append(branch)
    return active, branches


def _CreateUpdateBranch():
    logging.info('Creating update branch: %s', UPDATE_BRANCH_NAME)
    subprocess.check_call(['git', 'checkout', '-b', UPDATE_BRANCH_NAME])


def _UpdateWebRTCVersion(filename):
    with open(filename) as f:
        content = f.read()
    d = datetime.datetime.utcnow()
    # pylint: disable=line-too-long
    new_content = re.sub(
        r'WebRTC source stamp [0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}',
        r'WebRTC source stamp %02d-%02d-%02dT%02d:%02d:%02d' % (d.year,
                                                                d.month,
                                                                d.day,
                                                                d.hour,
                                                                d.minute,
                                                                d.second),
        content,
        flags=re.MULTILINE)
    # pylint: enable=line-too-long
    with open(filename, 'w') as f:
        f.write(new_content)


def _IsTreeClean():
    stdout = subprocess.check_output(['git', 'status', '--porcelain'])
    if len(stdout) == 0:
        return True
    return False


def _LocalCommit():
    logging.info('Committing changes locally.')
    d = datetime.datetime.utcnow()

    git_author = subprocess.check_output(['git', 'config',
                                          'user.email']).strip()
    commit_msg = ('Update WebRTC code version (%02d-%02d-%02dT%02d:%02d:%02d).'
                  '\n\nBug: None')
    commit_msg = commit_msg % (d.year, d.month, d.day, d.hour, d.minute,
                               d.second)
    subprocess.check_call(['git', 'add', '--update', '.'])
    subprocess.check_call(['git', 'commit', '-m', commit_msg])


def _UploadCL(commit_queue_mode):
    """Upload the committed changes as a changelist to Gerrit.

  commit_queue_mode:
    - 2: Submit to commit queue.
    - 1: Run trybots but do not submit to CQ.
    - 0: Skip CQ, upload only.
  """
    cmd = ['git', 'cl', 'upload', '--force', '--bypass-hooks',
           '--cc=""', '--bypass-watchlist']
    if commit_queue_mode >= 2:
        logging.info('Sending the CL to the CQ...')
        cmd.extend(['-o', 'label=Bot-Commit+1'])
        cmd.extend(['-o', 'label=Commit-Queue+2'])
    elif commit_queue_mode >= 1:
        logging.info('Starting CQ dry run...')
        cmd.extend(['-o', 'label=Commit-Queue+1'])
    subprocess.check_call(cmd)


def main():
    logging.basicConfig(level=logging.INFO)
    p = argparse.ArgumentParser()
    p.add_argument('--clean',
                   action='store_true',
                   default=False,
                   help='Removes any previous local update branch.')
    opts = p.parse_args()

    if opts.clean:
        _RemovePreviousUpdateBranch()

    if _GetLastAuthor() == 'webrtc-version-updater':
      logging.info('Last commit is a version change, skipping CL.')
      return 0

    version_filename = os.path.join(CHECKOUT_SRC_DIR, 'call', 'version.cc')
    _CreateUpdateBranch()
    _UpdateWebRTCVersion(version_filename)
    if _IsTreeClean():
        logging.info('No WebRTC version change detected, skipping CL.')
    else:
        _LocalCommit()
        logging.info('Uploading CL...')
        _UploadCL(2)
    return 0


if __name__ == '__main__':
  sys.exit(main())
