#!/usr/bin/env python

import errno

try:
  import json
except ImportError:
  import simplejson as json

import os
import re
import shutil
import sys

# set at init time
dst_dir = None
node_prefix = None # dst_dir without DESTDIR prefix
target_defaults = None
variables = None

def abspath(*args):
  path = os.path.join(*args)
  return os.path.abspath(path)

def load_config():
  s = open('config.gypi').read()
  s = re.sub(r'#.*?\n', '', s) # strip comments
  s = re.sub(r'\'', '"', s) # convert quotes
  return json.loads(s)

def try_unlink(path):
  try:
    os.unlink(path)
  except OSError, e:
    if e.errno != errno.ENOENT: raise

def try_symlink(source_path, link_path):
  print 'symlinking %s -> %s' % (source_path, link_path)
  try_unlink(link_path)
  os.symlink(source_path, link_path)

def try_mkdir_r(path):
  try:
    os.makedirs(path)
  except OSError, e:
    if e.errno != errno.EEXIST: raise

def try_rmdir_r(path):
  path = abspath(path)
  while path.startswith(dst_dir):
    try:
      os.rmdir(path)
    except OSError, e:
      if e.errno == errno.ENOTEMPTY: return
      if e.errno == errno.ENOENT: return
      raise
    path = abspath(path, '..')

def mkpaths(path, dst):
  if dst.endswith('/'):
    target_path = abspath(dst_dir, dst, os.path.basename(path))
  else:
    target_path = abspath(dst_dir, dst)
  return path, target_path

def try_copy(path, dst):
  source_path, target_path = mkpaths(path, dst)
  print 'installing %s' % target_path
  try_mkdir_r(os.path.dirname(target_path))
  try_unlink(target_path) # prevent ETXTBSY errors
  return shutil.copy2(source_path, target_path)

def try_remove(path, dst):
  source_path, target_path = mkpaths(path, dst)
  print 'removing %s' % target_path
  try_unlink(target_path)
  try_rmdir_r(os.path.dirname(target_path))

def install(paths, dst): map(lambda path: try_copy(path, dst), paths)
def uninstall(paths, dst): map(lambda path: try_remove(path, dst), paths)

def update_shebang(path, shebang):
  print 'updating shebang of %s to %s' % (path, shebang)
  s = open(path, 'r').read()
  s = re.sub(r'#!.*\n', '#!' + shebang + '\n', s)
  open(path, 'w').write(s)

def npm_files(action):
  target_path = 'lib/node_modules/npm/'

  # don't install npm if the target path is a symlink, it probably means
  # that a dev version of npm is installed there
  if os.path.islink(abspath(dst_dir, target_path)): return

  # npm has a *lot* of files and it'd be a pain to maintain a fixed list here
  # so we walk its source directory instead...
  for dirname, subdirs, basenames in os.walk('deps/npm', topdown=True):
    subdirs[:] = filter('test'.__ne__, subdirs) # skip test suites
    paths = [os.path.join(dirname, basename) for basename in basenames]
    action(paths, target_path + dirname[9:] + '/')

  # create/remove symlink
  link_path = abspath(dst_dir, 'bin/npm')
  if action == uninstall:
    action([link_path], 'bin/npm')
  elif action == install:
    try_symlink('../lib/node_modules/npm/bin/npm-cli.js', link_path)
    if os.environ.get('PORTABLE'):
      # This crazy hack is necessary to make the shebang execute the copy
      # of node relative to the same directory as the npm script. The precompiled
      # binary tarballs use a prefix of "/" which gets translated to "/bin/node"
      # in the regular shebang modifying logic, which is incorrect since the
      # precompiled bundle should be able to be extracted anywhere and "just work"
      shebang = '/bin/sh\n// 2>/dev/null; exec "`dirname "$0"`/node" "$0" "$@"'
    else:
      shebang = os.path.join(node_prefix, 'bin/node')
    update_shebang(link_path, shebang)
  else:
    assert(0) # unhandled action type

def subdir_files(path, dest, action):
  ret = {}
  for dirpath, dirnames, filenames in os.walk(path):
    files = [dirpath + '/' + f for f in filenames if f.endswith('.h')]
    ret[dest + dirpath.replace(path, '')] = files
  for subdir, files in ret.items():
    action(files, subdir + '/')

def files(action):
  action(['out/Release/node'], 'bin/node')

  # install unconditionally, checking if the platform supports dtrace doesn't
  # work when cross-compiling and besides, there's at least one linux flavor
  # with dtrace support now (oracle's "unbreakable" linux)
  action(['src/node.d'], 'lib/dtrace/')

  if 'freebsd' in sys.platform or 'openbsd' in sys.platform:
    action(['doc/node.1'], 'man/man1/')
  else:
    action(['doc/node.1'], 'share/man/man1/')

  if 'true' == variables.get('node_install_npm'): npm_files(action)

  action([
    'config.gypi',
    'src/node.h',
    'src/node_buffer.h',
    'src/node_internals.h',
    'src/node_object_wrap.h',
    'src/node_version.h',
  ], 'include/node/')

  if 'false' == variables.get('node_shared_cares'):
    subdir_files('deps/cares/include', 'include/node/', action)

  if 'false' == variables.get('node_shared_libuv'):
    subdir_files('deps/uv/include', 'include/node/', action)

  if 'false' == variables.get('node_shared_openssl'):
    action(['deps/openssl/config/opensslconf.h'], 'include/node/openssl/')
    subdir_files('deps/openssl/include/openssl', 'include/node/openssl/', action)

  if 'false' == variables.get('node_shared_v8'):
    subdir_files('deps/v8/include', 'include/node/', action)

  if 'false' == variables.get('node_shared_zlib'):
    action([
      'deps/zlib/zconf.h',
      'deps/zlib/zlib.h',
    ], 'include/node/')

def run(args):
  global dst_dir, node_prefix, target_defaults, variables

  # chdir to the project's top-level directory
  os.chdir(abspath(os.path.dirname(__file__), '..'))

  conf = load_config()
  variables = conf['variables']
  target_defaults = conf['target_defaults']

  # argv[2] is a custom install prefix for packagers (think DESTDIR)
  dst_dir = node_prefix = variables.get('node_prefix') or '/usr/local'
  if len(args) > 2: dst_dir = abspath(args[2] + '/' + dst_dir)

  cmd = args[1] if len(args) > 1 else 'install'
  if cmd == 'install': return files(install)
  if cmd == 'uninstall': return files(uninstall)
  raise RuntimeError('Bad command: %s\n' % cmd)

if __name__ == '__main__':
  run(sys.argv[:])
