#!/usr/bin/env python3
# Copyright (C) 2022 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.

import os
import sys
import re
import subprocess
import pathlib
import tempfile
import contextlib
import argparse
import itertools

ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
TOOLS_DIR = os.path.join(ROOT_DIR, "tools")
OUT_DIR = os.path.join(ROOT_DIR, "out", "tools")
NINJA = os.path.join(TOOLS_DIR, "ninja")
GN = os.path.join(TOOLS_DIR, "gn")
PROTOC_PATH = os.path.join(OUT_DIR, "protoc")
DESCRIPTOR_PATH = os.path.join(ROOT_DIR, "src", "trace_processor", "importers",
                               "proto", "atoms.descriptor")
PROTOBUF_BUILTINS_DIR = os.path.join(ROOT_DIR, "buildtools", "protobuf", "src")
PROTO_LOGGING_URL = "https://android.googlesource.com/platform/frameworks/proto_logging.git"
ATOM_RE = r"  message_type {\n.   name: \"Atom\"(\n    .+)+(\n  })"
FIELD_RE = r"    field {\n      name: \"([^\"]+)\"\n      number: ([0-9]+)"
EXTENSIONS_RE = r" extension {\n    name: \"([^\"]+)\"\n    extendee: \".android.os.statsd.Atom\"\n    number: ([0-9]+)(\n    .+)+(\n  })"
ATOM_IDS_PATH = os.path.join(ROOT_DIR, "protos", "perfetto", "config", "statsd",
                             "atom_ids.proto")

ATOM_IDS_TEMPLATE = """/*
 * Copyright (C) 2022 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.
 */
syntax = "proto2";

package perfetto.protos;

// This enum is obtained by post-processing
// AOSP/frameworks/proto_logging/stats/atoms.proto through
// AOSP/external/perfetto/tools/update-statsd-descriptor, which extracts one
// enum value for each proto field defined in the upstream atoms.proto.
enum AtomId {{
  ATOM_UNSPECIFIED = 0;
{atoms}
}}"""


def call(*cmd, stdin=None):
  try:
    return subprocess.check_output(cmd, stdin=stdin)
  except subprocess.CalledProcessError as e:
    print("Error running the command:")
    print(" ".join(cmd))
    print(e)
    exit(1)


# Extract core atoms. To do this we regex the pbtext
# of the descriptor. This is hopefully:
# - more stable than regexing atom.proto directly
# - less complicated than parsing finding, importing, and using the
#   Python protobuf library.
def atoms_from_descriptor():
  with contextlib.ExitStack() as stack:
    descriptor_in = stack.enter_context(open(DESCRIPTOR_PATH))
    pbtext = call(
        PROTOC_PATH,
        f"--proto_path={PROTOBUF_BUILTINS_DIR}",
        f"{PROTOBUF_BUILTINS_DIR}/google/protobuf/descriptor.proto",
        "--decode=google.protobuf.FileDescriptorSet",
        stdin=descriptor_in).decode("utf8")

    # Core atoms:
    atom_pbtext = re.search(ATOM_RE, pbtext, re.MULTILINE)[0]
    for m in re.finditer(FIELD_RE, atom_pbtext):
      yield m[1], m[2]

    # Extensions
    for m in re.finditer(EXTENSIONS_RE, pbtext):
      yield m[1], m[2]


def main():
  parser = argparse.ArgumentParser()
  parser.add_argument("--atoms-checkout")
  args = parser.parse_args()

  call(GN, "gen", OUT_DIR, "--args=is_debug=false")
  call(NINJA, "-C", OUT_DIR, "protoc")

  with contextlib.ExitStack() as stack:

    # Write the descriptor.
    if args.atoms_checkout:
      atoms_root = args.atoms_checkout
      proto_logging_dir = os.path.join(atoms_root, "frameworks",
                                       "proto_logging")
    else:
      atoms_root = stack.enter_context(tempfile.TemporaryDirectory())
      proto_logging_dir = os.path.join(atoms_root, "frameworks",
                                       "proto_logging")
      pathlib.Path(proto_logging_dir).mkdir(parents=True, exist_ok=True)
      call("git", "clone", PROTO_LOGGING_URL, proto_logging_dir)


    extensions_path = os.path.join(proto_logging_dir, "stats", "atoms")
    extensions = []
    if os.path.isdir(extensions_path):
      for dirpath, dirnames, filenames in os.walk(extensions_path):
        for name in filenames:
          if name.endswith(".proto"):
            path = os.path.join(dirpath, name)
            extensions.append(path)

    cmd = [
      f"--proto_path={PROTOBUF_BUILTINS_DIR}",
      f"--proto_path={atoms_root}",
      f"--descriptor_set_out={DESCRIPTOR_PATH}",
      "--include_imports",
      ] + extensions + [
      os.path.join(proto_logging_dir, "stats", "atoms.proto")
    ]
    call(PROTOC_PATH, *cmd)

    lines = []
    for name, field in atoms_from_descriptor():
      name = "ATOM_" + name.upper()
      lines.append(f"  {name} = {field};".format(name=name, field=field))
    atom_ids_out = stack.enter_context(open(ATOM_IDS_PATH, "w"))
    atom_ids_out.write(ATOM_IDS_TEMPLATE.format(atoms="\n".join(lines)))


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