#!/usr/bin/env python3
# Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.

from os import path

import argparse
import os
import subprocess
import sys

import jdk
import utils


def parse_arguments():
    parser = argparse.ArgumentParser(
        description='R8lib wrapper for retrace tool.')
    parser.add_argument('-c',
                        '--commit-hash',
                        '--commit_hash',
                        help='Commit hash to download r8lib map file for.',
                        default=None)
    parser.add_argument('--version',
                        help='Version to download r8lib map file for.',
                        default=None)
    parser.add_argument('--tag',
                        help='Tag to download r8lib map file for.',
                        default=None)
    parser.add_argument(
        '--exclude-deps',
        '--exclude_deps',
        default=None,
        action='store_true',
        help='Use the exclude-deps version of the mapping file.')
    parser.add_argument('--map', help='Path to r8lib map in text format.', default=None)
    parser.add_argument('--partition-map',
                        '--partition_map',
                        help='Path to r8lib map in ZIP partition format.',
                        default=None)
    parser.add_argument('--r8jar', help='Path to r8 jar.', default=None)
    parser.add_argument('--no-r8lib',
                        '--no_r8lib',
                        default=False,
                        action='store_true',
                        help='Use r8.jar and not r8lib.jar.')
    parser.add_argument(
        '--stacktrace',
        help='Path to stacktrace file (read from stdin if not passed).',
        default=None)
    parser.add_argument('--quiet',
                        default=None,
                        action='store_true',
                        help='Disables diagnostics printing to stdout.')
    parser.add_argument(
        '--debug-agent',
        '--debug_agent',
        default=None,
        action='store_true',
        help='Attach a debug-agent to the retracer java process.')
    parser.add_argument(
        '--regex',
        default=None,
        help='Sets a custom regular expression used for parsing')
    parser.add_argument('--verbose',
                        default=None,
                        action='store_true',
                        help='Enables verbose retracing.')
    parser.add_argument('--disable-map-validation',
                        default=None,
                        action='store_true',
                        help='Disable validation of map hash.')
    parser.add_argument(
        '--disable-partition-map',
        default=False,
        action='store_true',
        help='Disable use of partition map (unless one was explicitly specified'
            ' with --partition-map).')
    return parser.parse_args()


def get_map_file(args, temp):
    # Default to using the specified map file.
    if args.map:
        return (False, args.map)
    if args.partition_map:
        return (True, args.partition_map)

    for use_partition_map in ([False] if args.disable_partition_map else [True, False]):
        # Try to extract map from the tag/version options.
        map_path = utils.find_cloud_storage_file_from_options(
            'r8lib.jar_map.zip' if use_partition_map else 'r8lib.jar.map', args)
        if map_path:
            return (use_partition_map, map_path)

        # Try to extract map from the stack-trace source-file content.
        r8_source_file = get_r8_source_file_attribute(args.stacktrace)
        if r8_source_file:
            map_path = get_map_from_r8_source_file_attribute(
                args, r8_source_file, use_partition_map)
        if map_path:
            return (use_partition_map, map_path)

    # If no other map file was found, use the local mapping file.
    if args.r8jar:
        return (False, args.r8jar + ".map")
    return (False, utils.R8LIB_MAP)


# Extract the R8 source file attribute from the stack trace if present.
def get_r8_source_file_attribute(stacktrace):
    r8_source_file = None
    for line in open(stacktrace, 'r'):
        start = line.rfind("(R8_")
        if start > 0:
            end = line.find(":", start)
            content = line[start + 1:end]
            if r8_source_file:
                if content != r8_source_file:
                    print(
                        'WARNING: there are multiple distinct R8 source files:')
                    print(' ' + r8_source_file)
                    print(' ' + content)
            else:
                r8_source_file = content
    return r8_source_file


def get_map_from_r8_source_file_attribute(args, r8_source_file, use_partition_map):
    (header, r8_version_or_hash, maphash) = r8_source_file.split('_')
    # If the command-line specified --exclude-deps then assume it is as previous
    # versions will not be marked as such in the source-file line.
    is_excldeps = args.exclude_deps
    excldeps_start = r8_version_or_hash.find('+excldeps')
    if (excldeps_start > 0):
        is_excldeps = True
        r8_version_or_hash = r8_version_or_hash[0:excldeps_start]
    if len(r8_version_or_hash) < 40:
        args.version = r8_version_or_hash
    else:
        args.commit_hash = r8_version_or_hash
    map_path = None
    # First check local mapping file for map hash.
    if path.exists(utils.R8LIB_MAP) and get_hash_from_map_file(
            utils.R8LIB_MAP) == maphash:
        return utils.R8LIB_MAP
    try:
        # Look for mapping file on GCS based on the version or commit hash
        # found in the source file atttribute.
        map_path = utils.find_cloud_storage_file_from_options(
            'r8lib' + ('-exclude-deps' if is_excldeps else '')
            + ('.jar_map.zip' if use_partition_map else '.jar.map'),
            args)

        if map_path:
            # Partition map is not validated. The mapping file header is
            # in the METADATA blob together with some other imformation.
            if not args.disable_map_validation and not use_partition_map:
                check_maphash(map_path, maphash, args)
            return map_path
    except Exception as e:
        print(e)
        print('WARNING: Falling back to using local mapping file.')

    # If no other map file was found, use the local mapping file.
    if args.r8jar:
        return args.r8jar + ('_map.zip' if use_partition_map else ".map")
    return utils.R8LIB_PARTITION_MAP if use_partition_map else utils.R8LIB_MAP


def check_maphash(mapping_path, maphash, args):
    infile_maphash = get_hash_from_map_file(mapping_path)
    if infile_maphash != maphash:
        print('ERROR: The mapping file hash does not match the R8 line')
        print('  In mapping file: ' + infile_maphash)
        print('  In source file:  ' + maphash)
        if (not args.exclude_deps):
            print(
                'If this could be a version without internalized dependencies '
                + 'try passing --exclude-deps')
        sys.exit(1)


def get_hash_from_map_file(mapping_path):
    map_hash_header = "# pg_map_hash: SHA-256 "
    for line in open(mapping_path, 'r'):
        if line.startswith(map_hash_header):
            return line[len(map_hash_header):].strip()


def main():
    args = parse_arguments()
    with utils.TempDir() as temp:
        # Get the stack trace to retrace.
        if not args.stacktrace:
            if not args.quiet:
                print('Waiting for stack-trace input...')
            args.stacktrace = os.path.join(temp, 'stacktrace.txt')
            open(args.stacktrace, 'w').writelines(sys.stdin.readlines())

        (is_partition_map, map_path) = get_map_file(args, temp)
        return run(map_path,
                   is_partition_map,
                   args.stacktrace,
                   args.r8jar,
                   args.no_r8lib,
                   quiet=args.quiet,
                   debug=args.debug_agent,
                   regex=args.regex,
                   verbose=args.verbose)


def run(map_path,
        is_partition_map,
        stacktrace,
        r8jar,
        no_r8lib,
        quiet=False,
        debug=False,
        regex=None,
        verbose=False):
    retrace_args = [jdk.GetJavaExecutable()]

    if debug:
        retrace_args.append(
            '-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005'
        )

    if not r8jar:
        r8jar = utils.R8_JAR if no_r8lib else utils.R8LIB_JAR

    retrace_args += [
        '-cp', r8jar, 'com.android.tools.r8.retrace.Retrace'
    ]
    if is_partition_map:
        retrace_args.extend(['--partition-map', map_path])
    else:
        retrace_args.append(map_path)

    if regex:
        retrace_args.append('--regex')
        retrace_args.append(regex)

    if quiet:
        retrace_args.append('--quiet')

    if stacktrace:
        retrace_args.append(stacktrace)

    if verbose:
        retrace_args.append('--verbose')

    utils.PrintCmd(retrace_args, quiet=quiet)
    return subprocess.call(retrace_args)


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