#!/usr/bin/env python3

import argparse
from collections import deque
from pycman import config

parser = argparse.ArgumentParser(
  description='List all packages installed before one of their dependencies.'
)

parser.add_argument(
  'pkgs', metavar='<pkgname>', nargs='*',
  help='Limit output to the given dependencies.'
)

parser.add_argument(
  '-c', '--config', metavar='<path>', default='/etc/pacman.conf',
  help='Pacman configuration file. Default: %(default)s'
)

parser.add_argument(
  '-g', '--graph', action='store_true',
  help='Print a directed graph in graphviz dot format.'
)



def get_all_dependents(db, pkg):
  q = deque(pkg.compute_requiredby())
  ds = set()
  gs = set((pkg.name, d) for d in q)
  while q:
    n = q.popleft()
    if n in ds:
      continue
    else:
      ds.add(n)
      p = db.get_pkg(n)
      rs = p.compute_requiredby()
      q.extend(rs)
      gs |= set((n, r) for r in rs)
  return ds, gs



def print_graph(matches):
  print('digraph PKGS {')
  for n, d in matches:
    print('  "{}" -> "{}"'.format(n, d))
  print('}')



def main(args=None):
  pargs = parser.parse_args(args)
  h = config.init_with_config(pargs.config)
  old = set()
  ldb = h.get_localdb()
  graph = set()

  if pargs.pkgs:
    pkgs = list()
    for p in pargs.pkgs:
      pkg = ldb.get_pkg(p)
      if pkg is not None:
        pkgs.append(pkg)
  else:
    pkgs = ldb.pkgcache

#   pkgs = sorted(pkgs, key=lambda p: p.installdate, reverse=True)

  for pkg in pkgs:
    n = pkg.name
    if n in old:
      continue
    for r in pkg.compute_requiredby():
      rpkg = ldb.get_pkg(r)
      if pkg.installdate > rpkg.installdate:
        ds, gs = get_all_dependents(ldb, rpkg)
        old |= ds
        graph.add((n, rpkg.name))
        graph |= gs

  if pargs.graph:
    print_graph(sorted(graph))
  else:
    for o in sorted(old):
      print(o)

if __name__ == '__main__':
  try:
    main()
  except (KeyboardInterrupt, BrokenPipeError):
    pass
