#!/usr/bin/env python

#  Copyright 2018 The ANGLE 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.

# This tool will create a json description of the GN build environment that
# can then be used by gen_angle_android_bp.py to build an Android.bp file for
# the Android Soong build system.
# The input to this tool is a list of GN labels for which to capture the build
# information in json:
#
# Generating angle.json needs to be done from within a Chromium build:
#   cd <chromium>/src
#   gen_angle_gn_info_json.py //third_party/angle:libGLESv2 //third_party/angle:libEGL
#
# This will output an angle.json that can be copied to the angle directory
# within Android.
#
# Optional arguments:
#  --gn_out <file>  GN output config to use (e.g., out/Default or out/Debug.)
#  --output <file>  json file to create, default is angle.json
#

import argparse
import json
import logging
import subprocess
import sys


def get_json_description(gn_out, target_name):
    try:
        text_desc = subprocess.check_output(
            ['gn', 'desc', '--format=json', gn_out, target_name])
    except subprocess.CalledProcessError as e:
        logging.error("e.retcode = %s" % e.returncode)
        logging.error("e.cmd = %s" % e.cmd)
        logging.error("e.output = %s" % e.output)
    try:
        json_out = json.loads(text_desc)
    except ValueError:
        raise ValueError("Unable to decode JSON\ncmd: %s\noutput:\n%s" %
                         (subprocess.list2cmdline(['gn', 'desc', '--format=json',
                                                   gn_out, target_name]), text_desc))

    return json_out

def load_json_deps(desc, gn_out, target_name, all_desc, indent="  "):
    """Extracts dependencies from the given target json description
       and recursively extracts json descriptions.

       desc: json description for target_name that includes dependencies
       gn_out: GN output file with configuration info
       target_name: name of target in desc to lookup deps
       all_desc: dependent descriptions added here
       indent: Print with indent to show recursion depth
    """
    target = desc[target_name]
    text_descriptions = []
    for dep in target.get('deps', []):
        if dep not in all_desc:
            logging.debug("dep: %s%s" % (indent,dep))
            new_desc = get_json_description(gn_out, dep)
            all_desc[dep] = new_desc[dep]
            load_json_deps(new_desc, gn_out, dep, all_desc, indent+"  ")
        else:
            logging.debug("dup: %s%s" % (indent,dep))

def create_build_description(gn_out, targets):
    """Creates the JSON build description by running GN."""

    logging.debug("targets = %s" % targets)
    json_descriptions = {}
    for target in targets:
        logging.debug("target: %s" % (target))
        target_desc = get_json_description(gn_out, target)
        if (target in target_desc and target not in json_descriptions):
            json_descriptions[target] = target_desc[target]
            load_json_deps(target_desc, gn_out, target, json_descriptions)
        else:
            logging.debug("Invalid target: %s" % target)
    return json_descriptions


def main():
    logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
    parser = argparse.ArgumentParser(
        description='Generate json build information from a GN description.')
    parser.add_argument(
        '--gn_out',
        help=
        'GN output config to use (e.g., out/Default or out/Debug.)',
        default='out/Default',
    )
    parser.add_argument(
        '--output',
        help='json file to create',
        default='angle.json',
    )
    parser.add_argument(
        'targets',
        nargs=argparse.REMAINDER,
        help='Targets to include in the json (e.g., "//libEGL")')
    args = parser.parse_args()

    desc = create_build_description(args.gn_out, args.targets)
    fh = open(args.output,"w")
    fh.write(json.dumps(desc, indent=4, sort_keys=True))
    fh.close()

    print("Output written to: %s" % args.output)


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