#!/usr/bin/env python3
# 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

# This scans the IREE source tree for long path lengths, which are problematic
# on Windows: https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation
#
# We ultimately care that the build system is happy, but CMake on Windows in
# particular does not actually give early or easy to understand error messages,
# and developers/CI using Linux may still want to see warnings. We'll use
# relative directory path length as a reasonable heuristic for "will the build
# system be happy?", since CMake tends to create paths like this:
# `iree/compiler/.../Foo/CMakeFiles/iree_compiler_Foo_Foo.objects.dir/bar.obj`.
# Note that 'Foo' appears three times in that path, so that's typically the best
# place to trim characters (and not file names).
#
# To check that all relative paths are shorter than the default limit:
#   python check_path_lengths.py
#
# To check that all relative paths are shorter than a custom limit:
#   python check_path_lengths.py --limit=50

import argparse
import os
import pathlib
import sys


def parse_arguments():
  parser = argparse.ArgumentParser(description="Path length checker")
  # The default limit was selected based on repository state when this script
  # was added. If the max path length decreases, consider lowering this too.
  parser.add_argument("--limit",
                      help="Path length limit (inclusive)",
                      type=int,
                      default=75)
  parser.add_argument(
      "--include_tests",
      help=
      "Includes /test directories. False by default as these don't usually generate problematic files during the build",
      action="store_true",
      default=False)
  parser.add_argument("--verbose",
                      help="Outputs detailed information about path lengths",
                      action="store_true",
                      default=False)
  args = parser.parse_args()
  return args


def main(args):
  repo_root = pathlib.Path(__file__).parent.parent.parent

  # Just look at the compiler directory for now, since it has historically had
  # by far the longest paths.
  walk_root = os.path.join(repo_root, "compiler")

  longest_path_length = -1
  long_paths = []
  short_paths = []
  for dirpath, dirnames, _ in os.walk(walk_root):
    # Don't descend into test directories, since they typically don't generate
    # object files or binaries that could trip up the build system.
    if not args.include_tests and "test" in dirnames:
      dirnames.remove("test")

    path = pathlib.Path(dirpath).relative_to(repo_root).as_posix()
    if len(path) > args.limit:
      long_paths.append(path)
    else:
      short_paths.append(path)
    longest_path_length = max(longest_path_length, len(path))
  long_paths.sort(key=len)
  short_paths.sort(key=len)

  if args.verbose and short_paths:
    print(f"These paths are shorter than the limit of {args.limit} characters:")
    for path in short_paths:
      print("{:3d}, {}".format(len(path), path))

  if long_paths:
    print(f"These paths are longer than the limit of {args.limit} characters:")
    for path in long_paths:
      print("{:3d}, {}".format(len(path), path))
    print(
        f"Error: {len(long_paths)} source paths are longer than {args.limit} characters."
    )
    print("  Long paths can be problematic when building on Windows.")
    print("  Please look at the output above and trim the paths.")
    sys.exit(1)
  else:
    print(f"All path lengths are under the limit of {args.limit} characters.")


if __name__ == "__main__":
  main(parse_arguments())
