# Copyright (C) 2018 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Send notification email if new version is found.

Example usage:
external_updater_notifier \
    --history ~/updater/history \
    --generate_change \
    --recipients xxx@xxx.xxx \
    googletest
"""

from datetime import timedelta, datetime
import argparse
import json
import os
import re
import subprocess
import time

import git_utils

def parse_args():
    """Parses commandline arguments."""

    parser = argparse.ArgumentParser(
        description='Check updates for third party projects in external/.')
    parser.add_argument(
        '--history',
        help='Path of history file. If doesn'
        't exist, a new one will be created.')
    parser.add_argument(
        '--recipients',
        help='Comma separated recipients of notification email.')
    parser.add_argument(
        '--generate_change',
        help='If set, an upgrade change will be uploaded to Gerrit.',
        action='store_true', required=False)
    parser.add_argument(
        'paths', nargs='*',
        help='Paths of the project.')
    parser.add_argument(
        '--all', action='store_true',
        help='Checks all projects.')

    return parser.parse_args()


ANDROID_TOP = os.path.normpath(os.path.join(__file__, '../../..'))
def _get_android_top():
    return ANDROID_TOP


CHANGE_URL_PATTERN = r'(https:\/\/[^\s]*android-review[^\s]*) Upgrade'
CHANGE_URL_RE = re.compile(CHANGE_URL_PATTERN)


def _read_owner_file(proj):
    owner_file = os.path.join(_get_android_top(), 'external', proj, 'OWNERS')
    if not os.path.isfile(owner_file):
        return None
    with open(owner_file, 'r') as f:
        return f.read().strip()


def _send_email(proj, latest_ver, recipient, upgrade_log):
    print('Sending email for {}: {}'.format(proj, latest_ver))
    msg = "New version: {}".format(latest_ver)
    match = CHANGE_URL_RE.search(upgrade_log)
    if match is not None:
        msg += '\n\nAn upgrade change is generated at:\n{}'.format(
            match.group(1))

    owners = _read_owner_file(proj)
    if owners:
        msg += '\n\nOWNERS file: \n'
        msg += owners

    msg += '\n\n'
    msg += upgrade_log

    subprocess.run(['sendgmr', '--to=' + recipient,
                    '--subject=' + proj], check=True,
                   stdout=subprocess.PIPE, stderr=subprocess.PIPE,
                   input=msg, encoding='ascii')


NOTIFIED_TIME_KEY_NAME = 'latest_notified_time'


def _should_notify(latest_ver, proj_history):
    if latest_ver in proj_history:
        # Processed this version before.
        return False

    timestamp = proj_history.get(NOTIFIED_TIME_KEY_NAME, 0)
    time_diff = datetime.today() - datetime.fromtimestamp(timestamp)
    if git_utils.is_commit(latest_ver) and time_diff <= timedelta(days=30):
        return False

    return True


def _process_results(args, history, results):
    for proj, res in results.items():
        if 'latest' not in res:
            continue
        latest_ver = res['latest']
        current_ver = res['current']
        if latest_ver == current_ver:
            continue
        proj_history = history.setdefault(proj, {})
        if _should_notify(latest_ver, proj_history):
            upgrade_log = _upgrade(proj) if args.generate_change else ""
            try:
                _send_email(proj, latest_ver, args.recipients, upgrade_log)
                proj_history[latest_ver] = int(time.time())
                proj_history[NOTIFIED_TIME_KEY_NAME] = int(time.time())
            except subprocess.CalledProcessError as err:
                msg = """Failed to send email for {} ({}).
stdout: {}
stderr: {}""".format(proj, latest_ver, err.stdout, err.stderr)
                print(msg)


RESULT_FILE_PATH = '/tmp/update_check_result.json'


def send_notification(args):
    """Compare results and send notification."""
    results = {}
    with open(RESULT_FILE_PATH, 'r') as f:
        results = json.load(f)
    history = {}
    try:
        with open(args.history, 'r') as f:
            history = json.load(f)
    except FileNotFoundError:
        pass

    _process_results(args, history, results)

    with open(args.history, 'w') as f:
        json.dump(history, f, sort_keys=True, indent=4)


def _upgrade(proj):
    out = subprocess.run(['out/soong/host/linux-x86/bin/external_updater',
                          'update', '--branch_and_commit', '--push_change',
                          proj],
                         stdout=subprocess.PIPE, stderr=subprocess.PIPE,
                         cwd=_get_android_top())
    stdout = out.stdout.decode('utf-8')
    stderr = out.stderr.decode('utf-8')
    return """
====================
|    Debug Info    |
====================
-=-=-=-=stdout=-=-=-=-
{}

-=-=-=-=stderr=-=-=-=-
{}
""".format(stdout, stderr)


def _check_updates(args):
    params = ['out/soong/host/linux-x86/bin/external_updater',
              'check', '--json_output', RESULT_FILE_PATH,
              '--delay', '30']
    if args.all:
        params.append('--all')
    else:
        params += args.paths

    subprocess.run(params, cwd=_get_android_top())


def main():
    """The main entry."""

    args = parse_args()
    _check_updates(args)
    send_notification(args)


if __name__ == '__main__':
    main()
