#!/usr/bin/env python
#
# Copyright (c) 2013, 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 a build of the editor.
#
# Usage: ./tools/create_editor.py
#            [--mode <mode>] [--arch <arch>] [--out <output>] [--build <build>]
#
# DO NOT CALL THIS SCRIPT DIRECTLY, instead invoke:
# ./tools/build.py -mrelease editor

import glob
import optparse
import os
import shutil
import subprocess
import sys
import utils
import zipfile

from os.path import join

OUTPUT = None
BUILD = None

OS_CONFIG = {
  'win32': 'win32, win32',
  'linux': 'linux, gtk',
  'macos': 'macosx, cocoa'
}

ARCH_CONFIG = {
  'ia32': 'x86',
  'x64': 'x86_64'
}

def AntPath():
  parent = join('third_party', 'apache_ant', '1.8.4', 'bin')
  if utils.IsWindows():
    return join(parent, 'ant.bat')
  else:
    return join(parent, 'ant')


def ProcessEditorArchive(archive, outDir):
  tempDir = join(GetEditorTemp(), 'editor.out')
  try:
    os.makedirs(tempDir)
  except OSError:
    # Directory already exists.
    pass

  if utils.IsWindows():
    f = zipfile.ZipFile(archive)
    f.extractall(tempDir)
    f.close()
  else:
    subprocess.call(['unzip', '-q', archive, '-d', tempDir])

  for src in glob.glob(join(tempDir, 'dart', '*')):
    shutil.move(src, outDir)

  shutil.rmtree(tempDir)
  os.unlink(archive)


def GetEditorTemp():
  return join(BUILD, 'editor.build.temp')


def GetDownloadCache():
  return GetEclipseBuildRoot()


def GetEclipseBuildRoot():
  return join(BUILD, 'editor.build.cache')


def GetSdkPath():
  return join(os.path.dirname(OUTPUT), 'dart-sdk')


def GetOutputParent():
  return os.path.dirname(os.path.dirname(OUTPUT))


def BuildOptions():
  options = optparse.OptionParser(usage='usage: %prog [options] <output>')
  options.add_option("-m", "--mode", metavar='[debug,release]')
  options.add_option("-a", "--arch", metavar='[ia32,x64]')
  options.add_option("-o", "--out")
  options.add_option("-b", "--build")
  return options


def Main():
  global OUTPUT
  global BUILD

  parser = BuildOptions()
  (options, args) = parser.parse_args()

  if args:
    parser.print_help()
    return 1

  osName = utils.GuessOS()
  mode = 'debug'
  arch = utils.GuessArchitecture()

  if not options.build:
    print >> sys.stderr, 'Error: no --build option specified'
    exit(1)
  else:
    BUILD = options.build

  if not options.out:
    print >> sys.stderr, 'Error: no --out option specified'
    exit(1)
  else:
    # TODO(devoncarew): Currently we scrape the output path to determine the
    # mode and arch. This is fragile and should moved into one location
    # (utils.py?) or made more explicit.
    OUTPUT = options.out
    mode = ('release', 'debug')['Debug' in OUTPUT]
    arch = ('ia32', 'x64')['X64' in OUTPUT]

  # Use explicit mode and arch information.
  if options.mode:
    mode = options.mode
  if options.arch:
    arch = options.arch

  OUTPUT = os.path.abspath(OUTPUT)
  BUILD = os.path.abspath(BUILD)

  print "\nBuilding the editor"
  print "  config : %s, %s, %s" % (osName, arch, mode)
  print "  output : %s" % OUTPUT

  # Clean the editor output directory.
  print '\ncleaning %s' % OUTPUT
  shutil.rmtree(OUTPUT, True)

  # These are the valid eclipse build configurations that we can produce.
  # We synthesize these up from the OS_CONFIG and ARCH_CONFIG information.
  # macosx, cocoa, x86 & macosx, cocoa, x86_64
  # win32, win32, x86 & win32, win32, x86_64
  # linux, gtk, x86 & linux, gtk, x86_64

  buildConfig = OS_CONFIG[osName] + ', ' + ARCH_CONFIG[arch]

  print "\ninvoking build_rcp.xml with buildConfig = [%s]\n" % buildConfig

  sys.stdout.flush()
  sys.stderr.flush()

  buildScript = join('editor', 'tools', 'features',
                     'com.google.dart.tools.deploy.feature_releng',
                     'build_rcp.xml')
  build_cmd = [AntPath(),
      '-lib',
      join('third_party', 'bzip2', 'bzip2.jar'),
      '-Dbuild.out=' + OUTPUT,
      '-Dbuild.configs=' + buildConfig,
      '-Dbuild.revision=' + utils.GetSVNRevision(),
      '-Ddart.version.full=' + utils.GetVersion(),
      '-Dbuild.root=' + GetEclipseBuildRoot(),
      '-Dbuild.downloads=' + GetDownloadCache(),
      '-Dbuild.source=' + os.path.abspath('editor'),
      '-Dbuild.dart.sdk=' + GetSdkPath(),
      '-Dbuild.no.properties=true',
      '-buildfile',
      buildScript]
  print build_cmd
  buildRcpStatus = subprocess.call(build_cmd, shell=utils.IsWindows())

  if buildRcpStatus != 0:
    sys.exit(buildRcpStatus)

  # build_rcp.xml will put the built editor archive in the OUTPUT directory
  # (dart-editor-macosx.cocoa.x86.zip). It contains the editor application in a
  # dart/ subdirectory. We unzip the contents of the archive into OUTPUT. It
  # will use the ../dart-sdk directory as its SDK.
  archives = glob.glob(join(OUTPUT, '*.zip'))

  if archives:
    ProcessEditorArchive(archives[0], OUTPUT)

  if os.path.exists(GetEditorTemp()):
    shutil.rmtree(GetEditorTemp())

  print('\nEditor build successful')


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