#!/usr/bin/env python
#
# Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.
#
# A script which will be invoked from gyp to create an SDK.
#
# Usage: create_sdk.py sdk_directory
#
# The SDK will be used either from the command-line or from the editor.
# Top structure is
#
# ..dart-sdk/
# ....bin/
# ......dart or dart.exe (executable)
# ......dart.lib (import library for VM native extensions on Windows)
# ......dart2js
# ......dartanalyzer
# ......pub
# ......snapshots/
# ........utils_wrapper.dart.snapshot
# ........pub.dart.snapshot
# ....include/
# ......dart_api.h
# ......dart_debugger_api.h
# ......dart_mirrors_api.h
# ......dart_native_api.h
# ....lib/
# ......_internal/
# ......async/
# ......collection/
# ......_collection_dev/
# ......convert/
# ......core/
# ......html/
# ......io/
# ......isolate/
# ......js/
# ......json/
# ......math/
# ......mirrors/
# ......utf/
# ......typed_data/
# ....util/
# ......dartanalyzer/
# ........dartanalyzer.jar
# ........(third-party libraries for dart_analyzer)
# ......(more will come here)


import glob
import optparse
import os
import re
import sys
import subprocess
import tempfile
import utils

HOST_OS = utils.GuessOS()

# TODO(dgrove): Only import modules following Google style guide.
from os.path import basename, dirname, join, realpath, exists, isdir

# TODO(dgrove): Only import modules following Google style guide.
from shutil import copyfile, copymode, copytree, ignore_patterns, rmtree, move


def GetOptions():
  options = optparse.OptionParser(usage='usage: %prog [options]')
  options.add_option("--sdk_output_dir",
      help='Where to output the sdk')
  options.add_option("--snapshot_location",
      help='Location of the snapshots.')
  return options.parse_args()


def ReplaceInFiles(paths, subs):
  '''Reads a series of files, applies a series of substitutions to each, and
     saves them back out. subs should by a list of (pattern, replace) tuples.'''
  for path in paths:
    contents = open(path).read()
    for pattern, replace in subs:
      contents = re.sub(pattern, replace, contents)

    dest = open(path, 'w')
    dest.write(contents)
    dest.close()


def Copy(src, dest):
  copyfile(src, dest)
  copymode(src, dest)


def CopyShellScript(src_file, dest_dir):
  '''Copies a shell/batch script to the given destination directory. Handles
     using the appropriate platform-specific file extension.'''
  file_extension = ''
  if HOST_OS == 'win32':
    file_extension = '.bat'

  src = src_file + file_extension
  dest = join(dest_dir, basename(src_file) + file_extension)
  Copy(src, dest)


def CopyDartScripts(home, sdk_root):
  for executable in ['dart2js', 'dartanalyzer', 'dartdoc', 'pub']:
    CopyShellScript(os.path.join(home, 'sdk', 'bin', executable),
                    os.path.join(sdk_root, 'bin'))


def CopySnapshots(snapshots, sdk_root):
  for snapshot in ['dart2js', 'utils_wrapper', 'pub']:
    snapshot += '.dart.snapshot'
    copyfile(join(snapshots, snapshot),
             join(sdk_root, 'bin', 'snapshots', snapshot))


def Main(argv):
  # Pull in all of the gypi files which will be munged into the sdk.
  HOME = dirname(dirname(realpath(__file__)))

  (options, args) = GetOptions()

  SDK = options.sdk_output_dir
  SDK_tmp = '%s.tmp' % SDK

  SNAPSHOT = options.snapshot_location

  # TODO(dgrove) - deal with architectures that are not ia32.

  if exists(SDK):
    rmtree(SDK)

  if exists(SDK_tmp):
    rmtree(SDK_tmp)

  os.makedirs(SDK_tmp)

  # Create and populate sdk/bin.
  BIN = join(SDK_tmp, 'bin')
  os.makedirs(BIN)

  os.makedirs(join(BIN, 'snapshots'))

  # Copy the Dart VM binary and the Windows Dart VM link library
  # into sdk/bin.
  #
  # TODO(dgrove) - deal with architectures that are not ia32.
  build_dir = os.path.dirname(SDK)
  dart_file_extension = ''
  if HOST_OS == 'win32':
    dart_file_extension = '.exe'
    dart_import_lib_src = join(HOME, build_dir, 'dart.lib')
    dart_import_lib_dest = join(BIN, 'dart.lib')
    copyfile(dart_import_lib_src, dart_import_lib_dest)
  dart_src_binary = join(HOME, build_dir, 'dart' + dart_file_extension)
  dart_dest_binary = join(BIN, 'dart' + dart_file_extension)
  copyfile(dart_src_binary, dart_dest_binary)
  copymode(dart_src_binary, dart_dest_binary)
  # Strip the binaries on platforms where that is supported.
  if HOST_OS == 'linux':
    subprocess.call(['strip', dart_dest_binary])
  elif HOST_OS == 'macos':
    subprocess.call(['strip', '-x', dart_dest_binary])

  #
  # Create and populate sdk/include.
  #
  INCLUDE = join(SDK_tmp, 'include')
  os.makedirs(INCLUDE)
  copyfile(join(HOME, 'runtime', 'include', 'dart_api.h'),
           join(INCLUDE, 'dart_api.h'))
  copyfile(join(HOME, 'runtime', 'include', 'dart_debugger_api.h'),
           join(INCLUDE, 'dart_debugger_api.h'))
  copyfile(join(HOME, 'runtime', 'include', 'dart_mirrors_api.h'),
           join(INCLUDE, 'dart_mirrors_api.h'))
  copyfile(join(HOME, 'runtime', 'include', 'dart_native_api.h'),
           join(INCLUDE, 'dart_native_api.h'))

  #
  # Create and populate sdk/lib.
  #

  LIB = join(SDK_tmp, 'lib')
  os.makedirs(LIB)

  #
  # Create and populate lib/{core, crypto, isolate, json, utf, ...}.
  #

  os.makedirs(join(LIB, 'html'))

  for library in [join('_internal', 'compiler'),
                  join('_internal', 'dartdoc'),
                  join('_internal', 'pub', 'resource'),
                  join('_internal', 'lib'),
                  'async', 'collection', '_collection_dev', 'convert',
                  'core', 'crypto', 'io', 'isolate',
                  join('chrome', 'dart2js'), join('chrome', 'dartium'),
                  join('html', 'dart2js'), join('html', 'dartium'),
                  join('html', 'html_common'),
                  join('indexed_db', 'dart2js'), join('indexed_db', 'dartium'),
                  'js', 'json', 'math', 'mirrors', 'typed_data',
                  join('svg', 'dart2js'), join('svg', 'dartium'),
                  'utf',
                  join('web_audio', 'dart2js'), join('web_audio', 'dartium'),
                  join('web_gl', 'dart2js'), join('web_gl', 'dartium'),
                  join('web_sql', 'dart2js'), join('web_sql', 'dartium')]:
    copytree(join(HOME, 'sdk', 'lib', library), join(LIB, library),
             ignore=ignore_patterns('*.svn', 'doc', '*.py', '*.gypi', '*.sh',
                                    '.gitignore'))

  # Copy lib/_internal/libraries.dart.
  copyfile(join(HOME, 'sdk', 'lib', '_internal', 'libraries.dart'),
           join(LIB, '_internal', 'libraries.dart'))

  # Create and copy tools.
  UTIL = join(SDK_tmp, 'util')
  os.makedirs(UTIL)

  # Create and copy dartanalyzer into 'util'
  DARTANALYZER_SRC = join(HOME, build_dir, 'dartanalyzer')
  DARTANALYZER_DEST = join(UTIL, 'dartanalyzer')
  os.makedirs(DARTANALYZER_DEST)

  jarFiles = glob.glob(join(DARTANALYZER_SRC, '*.jar'))

  for jarFile in jarFiles:
    copyfile(jarFile, join(DARTANALYZER_DEST, os.path.basename(jarFile)))

  # Copy in 7zip for Windows.
  if HOST_OS == 'win32':
    copytree(join(HOME, 'third_party', '7zip'),
             join(SDK_tmp, 'lib', '_internal', 'pub', 'resource', '7zip'),
             ignore=ignore_patterns('.svn'))

  # Copy dart2js/dartdoc/pub.
  CopyDartScripts(HOME, SDK_tmp)
  CopySnapshots(SNAPSHOT, SDK_tmp)

  # Write the 'version' file
  version = utils.GetVersion()
  versionFile = open(os.path.join(SDK_tmp, 'version'), 'w')
  versionFile.write(version + '\n')
  versionFile.close()

  # Write the 'revision' file
  revision = utils.GetSVNRevision()

  if revision is not None:
    with open(os.path.join(SDK_tmp, 'revision'), 'w') as f:
      f.write(revision + '\n')
      f.close()

  Copy(join(HOME, 'README.dart-sdk'), join(SDK_tmp, 'README'))

  move(SDK_tmp, SDK)

if __name__ == '__main__':
  sys.exit(Main(sys.argv))
