#!/usr/bin/env fuchsia-vendored-python
#
# Copyright 2020 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""
generate fidl_project.json file declaring FIDL libraries

The first command line argument is the root $FUCHSIA_DIR.
The second command line argument is the path to generated_sources.json.
The third command line argument is the path to which the script will write
fidl_project.json.

This script reads the generated_sources.json file which contains the paths to
fidlc-generated JSON IR, and generates a fidl_project.json file which declares
all FIDL libraries along with their constituent files, dependencies, and build
artifacts (JSON IR and bindings). This is for use in the FIDL Language Server,
which uses fidl_project to do dependency resolution.
"""

import glob
import json
import os
import re
import sys
from pathlib import Path

# fidl_project.json schema: list of Library
# where Library is
# {
#     "name": string,
#     "files": []string,
#     "json": string,
#     "deps": []string,
#     "bindings": {
#         "hlcpp": {},
#         "llcpp": {},
#         "rust": {},
#         "go": {},
#         "dart": {},
#         ...
#     }
# }

# https://fuchsia.dev/fuchsia-src/development/languages/fidl/reference/language.md#identifiers
identifier_pattern = r"[a-zA-Z](?:[a-zA-Z0-9_]*[a-zA-Z0-9])?"

# Although "library" can be used anywhere (e.g. as a type name), this regex
# is robust because the the library declaration must appear at the top of
# the file (only comments and whitespace can precede it).
library_pattern = (
    r"^(?:\s*//[^\n]*\n)*\s*"
    + r"library\s+("
    + identifier_pattern
    + r"(?:\."
    + identifier_pattern
    + r")*"
    + r")\s*;"
)


def find_files(library_name, library_json, fuchsia_dir=""):
    pattern = r"^fidling\/gen\/([\w\.\/-]+)\/[\w\-. ]+\.fidl\.json$"
    result = re.search(pattern, library_json)
    if not result or not result.group(1):
        return []

    fidl_dir = Path(f"{fuchsia_dir}/{result.group(1)}")
    globs = [
        fidl_dir.glob("*.fidl"),
        fidl_dir.parent.glob("*.fidl"),
    ]

    files = []
    for glob in globs:
        for file in glob:
            # Read in FIDL file
            with open(file, "r") as f:
                # Parse `library` decl
                result = re.search(library_pattern, f.read())
                # Check that it matches library name
                if not result or not result.group(1):
                    continue
                if result.group(1) != library_name:
                    continue
            files.append(str(file))
    return files


def find_deps(library_json, fuchsia_dir=""):
    library_json_path = Path(f"{fuchsia_dir}/out/default/{library_json}")

    if not os.path.isfile(library_json_path):
        return None

    with open(library_json_path, "r") as f:
        library = json.load(f)
        deps = library["library_dependencies"]
        deps = [dep["name"] for dep in deps]
        return deps


def gen_fidl_project(
    fuchsia_dir="", generated_sources_path="", fidl_project_path=""
):
    result = []
    with open(generated_sources_path, "r") as f:
        artifacts = json.load(f)

    processed = set()
    for artifact in artifacts:
        if artifact in processed:
            continue

        if not artifact.endswith(".fidl.json"):
            continue

        deps = find_deps(artifact, fuchsia_dir=fuchsia_dir)
        if deps is None:
            continue

        # Get JSON filename out of artifact
        library_name = os.path.basename(artifact)
        # Remove .fidl.json suffix
        library_name = library_name[:-10]

        processed.add(artifact)
        result.append(
            {
                "name": library_name,
                "json": f"{fuchsia_dir}/out/default/{artifact}",
                "files": find_files(
                    library_name, artifact, fuchsia_dir=fuchsia_dir
                ),
                "deps": deps,
                "bindings": {},  # TODO
            }
        )

    with open(fidl_project_path, "w") as f:
        json.dump(result, f, indent=4, sort_keys=True)


if __name__ == "__main__":
    if len(sys.argv) < 4:
        print("Please run this script as:")
        print(
            "  fx exec scripts/generate-fidl-project.py <root/build/dir> <generated_sources.json> <fidl_project.json>"
        )
        sys.exit(1)

    gen_fidl_project(
        fuchsia_dir=sys.argv[1],
        generated_sources_path=sys.argv[2],
        fidl_project_path=sys.argv[3],
    )
