#!/usr/bin/env vpython3
# Copyright 2025 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Automatically updates the .proto files in this directory."""

import json
import os
import re
import tarfile

from pathlib import Path

import requests

BASE_URL = "https://chromium.googlesource.com/infra/turboci/proto"
LOG_URL = BASE_URL + "/+log/main/{}?format=JSON&n=1"
TAR_URL = BASE_URL + "/+archive/{}/{}.tar.gz"

REPO_PATH = "turboci/data/chrome/depot_tools"


def print_commit_message(prev_commit: str, target: str):
  print("{0:=^80}".format(" START[Commit Message] "))
  print("[TurboCI] Import latest protos.")
  print()
  changelog = f"{BASE_URL}/+log/{prev_commit}..{target}"
  print(f"Changelog: {changelog}")
  print()
  clog = json.loads(requests.get(f"{changelog}?format=JSON").text[4:])
  for commit in clog["log"]:
    first_line = commit["message"].split("\n")[0]
    print(f"{commit['commit'][:8]} {first_line}")
  print()
  print("{0:=^80}".format(" END[Commit Message] "))


def main():
  """Automatically updates the .proto files in this directory."""
  this_dir = Path(__file__).parent

  readme_path = this_dir / "README.md"

  with open(readme_path, "r") as rmd:
    prev_commit = re.match(
      r".*/([a-f0-9]{40}|[a-f0-9]{64})/.*",
      rmd.read(),
      re.MULTILINE | re.DOTALL,
    ).group(1)

  to_remove = set()
  for root, _, files in os.walk(this_dir):
    for file in files:
      if file.endswith(".proto"):
        to_remove.add(Path(root) / file)

  resp = requests.get(LOG_URL.format(REPO_PATH))
  target = str(json.loads(resp.text[4:])["log"][0]["commit"])

  if prev_commit == target:
    print("Nothing to update.")
    return

  print(f"Updating to {target!r}")

  base_dir = this_dir.parent / REPO_PATH
  resp = requests.get(TAR_URL.format(target, REPO_PATH), stream=True).raw
  with tarfile.open(mode="r", fileobj=resp) as tar:
    for item in tar:
      if not item.name.endswith(".proto"):
        continue
      if item.name.endswith("_test.proto"):
        print(f"Skipping {item.name!r}")
        continue
      if "internal" in item.name or "googleapis" in item.name:
        print(f"Skipping {item.name!r}")
        continue
      print(f"Extracting {item.name!r}")
      tar.extract(item, path=base_dir)
      to_remove.discard(base_dir / item.name)

  if to_remove:
    print("Removing stale proto")
    for file in to_remove:
      os.remove(file)

  with open(readme_path, "w") as rmd:
    print("Generated by update.py. DO NOT EDIT.", file=rmd)
    print("These protos were copied from:", file=rmd)
    print(f"{BASE_URL}/+/{target}/{REPO_PATH}", file=rmd)

  print_commit_message(prev_commit, target)

  print("Done.")


if __name__ == "__main__":
  main()
