# 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()


def _get_android_top():
    return os.environ['ANDROID_BUILD_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

    print(_get_android_top())
    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()
