#!/usr/bin/env python
# Copyright 2022 The IREE Authors
#
# Licensed under the Apache License v2.0 with LLVM Exceptions.
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

# Pushes module patches to an appropriate repository.
#
# Typical steps:
# 1. Advance the main branches on our forks to get all upstream commits
#    (if you forget to do this, your cherry-pick will likely complain about
#    a bad ref).
# 2. In your submodule:
#      git fetch
#      git cherry-pick <some commit>
# 3. Run this script from the main IREE repository (one of the following):
#      patch_module.py --module=llvm-project
#      patch_module.py --module=stablehlo
# 4. Send a PR on the main IREE repo to bump the submodule. Be sure to include
#    the name of the patch branch for posterity.

import argparse
from datetime import date
import os
import sys

import iree_utils
import iree_modules

PATCH_REMOTE_ALIAS = "patched"


def main(args):
  module_info = iree_modules.MODULE_INFOS.get(args.module)
  if not module_info:
    raise SystemExit(f"ERROR: Bad value for --module. Must be one of: "
                     f"{', '.join(iree_modules.MODULE_INFOS.keys())}")

  if args.command == "patch":
    main_patch(args, module_info)
  else:
    raise SystemExit(
        f"ERROR: Unrecognized --command. Must be one of: patch, unpatch")


def main_patch(args, module_info: iree_modules.ModuleInfo):
  module_root = os.path.join(iree_utils.get_repo_root(), module_info.path)
  setup_module_remotes(module_root, module_info)

  branch_name = find_unused_branch_name(module_info)
  print(f"Allocated branch: {branch_name}")
  current_commit, summary = iree_utils.git_current_commit(repo_dir=module_root)
  print(f"Module is currently at: {summary}")
  print(
      f"*** Pushing branch {branch_name} to {module_info.fork_repository_push} ***"
  )
  print(f"(Please ignore any messages below about creating a PR)\n")
  iree_utils.git_exec([
      "push", PATCH_REMOTE_ALIAS, f"{current_commit}:refs/heads/{branch_name}"
  ],
                      repo_dir=module_root)
  print(f"*** Branch {branch_name} pushed ***")

  print(f"******* Congratulations *******")
  print(
      f"You have pushed your commits to {branch_name} on {module_info.fork_repository_push}."
  )
  print(
      f"Your main repository should now show that the submodule has been edited."
  )
  print(f"Make a commit, referencing the above branch cherry-picks and ")
  print(f"land the resulting PR.")
  print(f"You can push more commits to this module's patch branch via:")
  print(
      f"  (cd {module_info.path} && git push {PATCH_REMOTE_ALIAS} HEAD:{branch_name})"
  )


def setup_module_remotes(module_root: str,
                         module_info: iree_modules.ModuleInfo):
  iree_utils.git_setup_remote(PATCH_REMOTE_ALIAS,
                              url=module_info.fork_repository_push,
                              repo_dir=module_root)


def find_unused_branch_name(module_info: iree_modules.ModuleInfo):
  branch_base = f"{module_info.branch_prefix}{date.today().strftime('%Y%m%d')}"
  branch_name = branch_base
  existing_branches = iree_utils.git_ls_remote_branches(
      module_info.fork_repository_pull,
      filter=[f"refs/heads/{module_info.branch_prefix}*"])
  i = 1
  while branch_name in existing_branches:
    branch_name = f"{branch_base}.{i}"
    i += 1
  return branch_name


def parse_arguments(argv):
  parser = argparse.ArgumentParser(description="IREE Submodule Patcher")
  parser.add_argument("--module", help="Submodule to operate on", default=None)
  parser.add_argument("--command", help="Command to execute", default="patch")
  args = parser.parse_args(argv)
  return args


if __name__ == "__main__":
  main(parse_arguments(sys.argv[1:]))
