#!/usr/bin/env python
#####################
{{generated_file_remark}}

from __future__ import print_function
import argparse
import os
import shlex
import subprocess
import sys

package_def = {{package_def}}

parser = argparse.ArgumentParser()
parser.add_argument('packages', nargs='*')
parser.add_argument('-e', '--develop', action='store_true', help='Perform a normal install of the packages.')
parser.add_argument('-v', '--verbose', action='store_true', help='Print the Pip command that is run.')
parser.add_argument('-q', '--quiet', action='store_true', help='Capture Pip output.')
parser.add_argument('--extras', default='', help='Comma-separated extras to install.')
parser.add_argument('--uninstall', action='store_true', help='Uninstall the packages instead.')
parser.add_argument('--pip-args', nargs='...', help='Additional arguments to pass to Pip.', default=[])
args = parser.parse_args()

if args.develop and args.uninstall:
  parser.error('conflicting options: --develop and --uninstall')

def _resolve(result, pkg_names, extras=(), visited=None):
  if visited is None:
    visited = set()

  for pkg_name in (x for x in pkg_names if x not in visited):
    visited.add(pkg_name)
    package = next((x for x in package_def if x['name'] == pkg_name), None)
    if package is None:
      parser.error('not a package of this monorepo: {0}'.format(pkg_name))

    _resolve(result, package['requires'], extras, visited)
    for extra in filter(bool, extras):
      _resolve(result, package['extra_requires'].get(extra, []))

    if extras:
      pkg_name += '[' + ','.join(extras) + ']'
    result.append(pkg_name)

install_packages = []
_resolve(install_packages, (args.packages or (x['name'] for x in package_def)), list(filter(bool, args.extras.split(','))))

python = os.getenv('PYTHON', 'python')
pip = shlex.split(os.getenv('PYTHON_PIP', '"{0}" -m pip'.format(python)).replace('$PYTHON', python))
command = pip + ['uninstall' if args.uninstall else 'install']
if args.verbose:
  command.append('-v')
for pkgname in install_packages:
  if args.develop and not args.uninstall:
    command.append('-e')
  command.append(pkgname if args.uninstall else './' + pkgname)
if args.uninstall:
  command.append('-y')
command += args.pip_args

project_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

stdout, stderr = None, None
if args.verbose:
  print('Running command in working directory', project_dir)
  print('$', ' '.join(command))
elif args.quiet:
  stdout = subprocess.PIPE
  stderr = subprocess.STDOUT
  print('Installing', ' '.join(args.packages))

proc = subprocess.Popen(command, cwd=project_dir, stdout=stdout, stderr=stderr)
stdout, _ = proc.communicate()
if args.quiet and proc.returncode != 0:
  print(stdout, file=sys.stderr)
sys.exit(proc.returncode)
