#! /usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (C) 2016 and later: Unicode, Inc. and others.
# License & terms of use: http://www.unicode.org/copyright.html
# Copyright (C) 2011-2015, International Business Machines
# Corporation and others. All Rights Reserved.
#
# file name: depstest.py
#
# created on: 2011may24

"""ICU dependency tester.

This probably works only on Linux.

The exit code is 0 if everything is fine, 1 for errors, 2 for only warnings.

Sample invocation:
  ~/svn.icu/trunk/src/source/test/depstest$ ./depstest.py ~/svn.icu/trunk/dbg
"""

__author__ = "Markus W. Scherer"

import glob
import os.path
import subprocess
import sys

import dependencies

_ignored_symbols = set()
_obj_files = {}
_symbols_to_files = {}
_return_value = 0

# Classes with vtables (and thus virtual methods).
_virtual_classes = set()
# Classes with weakly defined destructors.
# nm shows a symbol class of "W" rather than "T".
_weak_destructors = set()

def _ReadObjFile(root_path, library_name, obj_name):
  global _ignored_symbols, _obj_files, _symbols_to_files
  global _virtual_classes, _weak_destructors
  lib_obj_name = library_name + "/" + obj_name
  if lib_obj_name in _obj_files:
    print "Warning: duplicate .o file " + lib_obj_name
    _return_value = 2
    return

  path = os.path.join(root_path, library_name, obj_name)
  nm_result = subprocess.Popen(["nm", "--demangle", "--format=sysv",
                                "--extern-only", "--no-sort", path],
                               stdout=subprocess.PIPE).communicate()[0]
  obj_imports = set()
  obj_exports = set()
  for line in nm_result.splitlines():
    fields = line.split("|")
    if len(fields) == 1: continue
    name = fields[0].strip()
    # Ignore symbols like '__cxa_pure_virtual',
    # 'vtable for __cxxabiv1::__si_class_type_info' or
    # 'DW.ref.__gxx_personality_v0'.
    # '__dso_handle' belongs to __cxa_atexit().
    if (name.startswith("__cxa") or "__cxxabi" in name or "__gxx" in name or
        name == "__dso_handle"):
      _ignored_symbols.add(name)
      continue
    type = fields[2].strip()
    if type == "U":
      obj_imports.add(name)
    else:
      obj_exports.add(name)
      _symbols_to_files[name] = lib_obj_name
      # Is this a vtable? E.g., "vtable for icu_49::ByteSink".
      if name.startswith("vtable for icu"):
        _virtual_classes.add(name[name.index("::") + 2:])
      # Is this a destructor? E.g., "icu_49::ByteSink::~ByteSink()".
      index = name.find("::~")
      if index >= 0 and type == "W":
        _weak_destructors.add(name[index + 3:name.index("(", index)])
  _obj_files[lib_obj_name] = {"imports": obj_imports, "exports": obj_exports}

def _ReadLibrary(root_path, library_name):
  obj_paths = glob.glob(os.path.join(root_path, library_name, "*.o"))
  for path in obj_paths:
    _ReadObjFile(root_path, library_name, os.path.basename(path))

def _Resolve(name, parents):
  global _ignored_symbols, _obj_files, _symbols_to_files, _return_value
  item = dependencies.items[name]
  item_type = item["type"]
  if name in parents:
    sys.exit("Error: %s %s has a circular dependency on itself: %s" %
             (item_type, name, parents))
  # Check if already cached.
  exports = item.get("exports")
  if exports != None: return item
  # Calculcate recursively.
  parents.append(name)
  imports = set()
  exports = set()
  system_symbols = item.get("system_symbols")
  if system_symbols == None: system_symbols = item["system_symbols"] = set()
  files = item.get("files")
  if files:
    for file_name in files:
      obj_file = _obj_files[file_name]
      imports |= obj_file["imports"]
      exports |= obj_file["exports"]
  imports -= exports | _ignored_symbols
  deps = item.get("deps")
  if deps:
    for dep in deps:
      dep_item = _Resolve(dep, parents)
      # Detect whether this item needs to depend on dep,
      # except when this item has no files, that is, when it is just
      # a deliberate umbrella group or library.
      dep_exports = dep_item["exports"]
      dep_system_symbols = dep_item["system_symbols"]
      if files and imports.isdisjoint(dep_exports) and imports.isdisjoint(dep_system_symbols):
        print "Info:  %s %s  does not need to depend on  %s\n" % (item_type, name, dep)
      # We always include the dependency's exports, even if we do not need them
      # to satisfy local imports.
      exports |= dep_exports
      system_symbols |= dep_system_symbols
  item["exports"] = exports
  item["system_symbols"] = system_symbols
  imports -= exports | system_symbols
  for symbol in imports:
    for file_name in files:
      if symbol in _obj_files[file_name]["imports"]:
        neededFile = _symbols_to_files.get(symbol)
        if neededFile in dependencies.file_to_item:
          neededItem = "but %s does not depend on %s (for %s)" % (name, dependencies.file_to_item[neededFile], neededFile)
        else:
          neededItem = "- is this a new system symbol?"
        sys.stderr.write("Error: in %s %s: %s imports %s %s\n" %
                         (item_type, name, file_name, symbol, neededItem))
    _return_value = 1
  del parents[-1]
  return item

def Process(root_path):
  """Loads dependencies.txt, reads the libraries' .o files, and processes them.

  Modifies dependencies.items: Recursively builds each item's system_symbols and exports.
  """
  global _ignored_symbols, _obj_files, _return_value
  global _virtual_classes, _weak_destructors
  dependencies.Load()
  for name_and_item in dependencies.items.iteritems():
    name = name_and_item[0]
    item = name_and_item[1]
    system_symbols = item.get("system_symbols")
    if system_symbols:
      for symbol in system_symbols:
        _symbols_to_files[symbol] = name
  for library_name in dependencies.libraries:
    _ReadLibrary(root_path, library_name)
  o_files_set = set(_obj_files.keys())
  files_missing_from_deps = o_files_set - dependencies.files
  files_missing_from_build = dependencies.files - o_files_set
  if files_missing_from_deps:
    sys.stderr.write("Error: files missing from dependencies.txt:\n%s\n" %
                     sorted(files_missing_from_deps))
    _return_value = 1
  if files_missing_from_build:
    sys.stderr.write("Error: files in dependencies.txt but not built:\n%s\n" %
                     sorted(files_missing_from_build))
    _return_value = 1
  if not _return_value:
    for library_name in dependencies.libraries:
      _Resolve(library_name, [])
  if not _return_value:
    virtual_classes_with_weak_destructors = _virtual_classes & _weak_destructors
    if virtual_classes_with_weak_destructors:
      sys.stderr.write("Error: Some classes have virtual methods, and "
                       "an implicit or inline destructor "
                       "(see ICU ticket #8454 for details):\n%s\n" %
                       sorted(virtual_classes_with_weak_destructors))
      _return_value = 1

def main():
  global _return_value
  if len(sys.argv) <= 1:
    sys.exit(("Command line error: " +
             "need one argument with the root path to the built ICU libraries/*.o files."))
  Process(sys.argv[1])
  if _ignored_symbols:
    print "Info: ignored symbols:\n%s" % sorted(_ignored_symbols)
  if not _return_value:
    print "OK: Specified and actual dependencies match."
  else:
    print "Error: There were errors, please fix them and re-run. Processing may have terminated abnormally."
  return _return_value

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