/*
 * Copyright 2000-2014 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import org.jetbrains.jps.gant.JpsGantTool
import org.jetbrains.jps.gant.TeamCityBuildInfoPrinter
import org.jetbrains.jps.model.java.JavaSourceRootType
import org.jetbrains.jps.model.module.JpsModule

includeTool << JpsGantTool

binding.setVariable("p", {String key ->
  return getProperty(key) as String
})

binding.setVariable("guessJdk", {
  String javaHome = p("java.home")

  if (new File(javaHome).getName() == "jre") {
    javaHome = new File(javaHome).getParent()
  }

  return javaHome
})

binding.setVariable("includeFile", {String filePath ->
  Script s = groovyShell.parse(new File(filePath))
  s.setBinding(binding)
  s
})

binding.setVariable("isMac", {
  return System.getProperty("os.name").toLowerCase().startsWith("mac")
})

binding.setVariable("isWin", {
  return System.getProperty("os.name").toLowerCase().startsWith("windows")
})

binding.setVariable("isEap", {
  return "true" == p("component.version.eap")
})

binding.setVariable("mem32", "-server -Xms128m -Xmx512m -XX:MaxPermSize=250m -XX:ReservedCodeCacheSize=64m")
binding.setVariable("mem64", "-Xms128m -Xmx750m -XX:MaxPermSize=350m -XX:ReservedCodeCacheSize=96m")
binding.setVariable("common_vmoptions", "-ea -Dsun.io.useCanonCaches=false -Djava.net.preferIPv4Stack=true " +
                                        "-Djsse.enableSNIExtension=false " +
                                        "-XX:+UseCodeCacheFlushing -XX:+UseConcMarkSweepGC -XX:SoftRefLRUPolicyMSPerMB=50")

binding.setVariable("vmOptions", { "$common_vmoptions ${isEap() ? '-XX:+HeapDumpOnOutOfMemoryError' : ''}".trim() })
binding.setVariable("vmOptions32", { "$mem32 ${vmOptions()}".trim() })
binding.setVariable("vmOptions64", { "$mem64 ${vmOptions()}".trim() })

binding.setVariable("yjpOptions", { String systemSelector, String platformSuffix = "" ->
  "-agentlib:yjpagent$platformSuffix=disablej2ee,disablealloc,disabletracing,onlylocal,builtinprobes=none,disableexceptiontelemetry,delay=10000,sessionname=$systemSelector".trim()
})
binding.setVariable("vmOptions32yjp", { String systemSelector ->
  "${vmOptions32()} ${yjpOptions(systemSelector)}".trim()
})
binding.setVariable("vmOptions64yjp", { String systemSelector ->
  "${vmOptions64()} ${yjpOptions(systemSelector, "64")}".trim()
})

binding.setVariable("isDefined", {String key ->
  try {
    this[key]
    return true
  }
  catch (MissingPropertyException ignored) {
    return false
  }
})

private String require(String key) {
  try {
    this[key]
  }
  catch (MissingPropertyException ignored) {
    projectBuilder.error("Property $key is required")
  }
}

private String require(String key, String defaultValue) {
  try {
    this[key]
  }
  catch (MissingPropertyException ignored) {
    projectBuilder.info("$key is not defined. Defaulting to $defaultValue")
    this[key] = defaultValue
  }
}

binding.setVariable("requireProperty", {String key, String defaultValue = null ->
  if (defaultValue == null) {
    require(key)
  }
  else {
    require(key, defaultValue)
  }
})

binding.setVariable("guessHome", {
  // Current file is supposed to be at build/scripts/release.gant path
  new File(requireProperty("gant.file").substring("file:".length())).getParentFile().getParentFile().getParent()
})

binding.setVariable("loadProject", {
  requireProperty("jdkHome", guessJdk())
  def mac = isMac()
  jdk("IDEA jdk", jdkHome) {
    if (!mac) {
      classpath "$jdkHome/lib/tools.jar"
    }
  }
  projectBuilder.dataStorageRoot = new File("$home/.jps-build-data")
  loadProjectFromPath(home)
})

boolean hasSourceRoots(JpsModule module) {
  return module.getSourceRoots(JavaSourceRootType.SOURCE).iterator().hasNext()
}

binding.setVariable("findModule", {String name ->
  project.modules.find { it.name == name }
})

binding.setVariable("allModules", {
  return project.modules
})

binding.setVariable("printUnusedModules", {Set<String> usedModules ->
  allModules().each {JpsModule m ->
    if (!usedModules.contains(m.name) && hasSourceRoots(m)) {
      projectBuilder.warning("Module $m.name is not used in project layout")
    }
  }
})

requireProperty("home", guessHome())

String readSnapshotBuild() {
  def file = new File("$home/community/build.txt")
  if (!file.exists()) {
    file = new File("$home/build.txt")
  }

  return file.readLines().get(0)
}

binding.setVariable("snapshot", readSnapshotBuild())

projectBuilder.buildInfoPrinter = new TeamCityBuildInfoPrinter()
projectBuilder.compressJars = false

binding.setVariable("notifyArtifactBuilt", { String artifactPath ->
  if (!artifactPath.startsWith(home)) {
    projectBuilder.error("Artifact path $artifactPath should start with $home")
  }
  def relativePath = artifactPath.substring(home.length())
  if (relativePath.startsWith("/")) {
    relativePath = relativePath.substring(1)
  }
  def file = new File(artifactPath)
  if (file.isDirectory()) {
    relativePath += "=>" + file.name
  }
  projectBuilder.info("##teamcity[publishArtifacts '$relativePath']")
})

def suspendUntilDebuggerConnect = System.getProperty("debug.suspend") ?: "n"
def debugPort = System.getProperty("debug.port") ?: 5555
if (suspendUntilDebuggerConnect == 'y') {
  println """\
------------->----------- This process is suspended until remote debugger connects to the port $debugPort ----<----
-------------------------------------------^------^------^------^------^------^------^-----------------------
"""
}

binding.setVariable("patchFiles", { List files, Map args, String marker = "__" ->
  files.each { file ->
    args.each { arg ->
      ant.replace(file: file, token: "${marker}${arg.key}${marker}", value:  arg.value)
    }
  }
})

binding.setVariable("copyAndPatchFile", { String file, String target, Map args, String marker = "__" ->
  ant.copy(file: file, tofile: target, overwrite: "true") {
    filterset(begintoken: marker, endtoken: marker) {
      args.each {
        filter(token: it.key, value: it.value)
      }
    }
  }
})

binding.setVariable("copyAndPatchFiles", { Closure files, String target, Map args, String marker = "__" ->
  ant.copy(todir: target, overwrite: "true") {
    files()

    filterset(begintoken: marker, endtoken: marker) {
      args.each {
        filter(token: it.key, value: it.value)
      }
    }
  }
})

binding.setVariable("wireBuildDate", { String buildNumber, String appInfoFile ->
  ant.tstamp()
  patchFiles([appInfoFile], ["BUILD_NUMBER": buildNumber, "BUILD_DATE": DSTAMP])
})

binding.setVariable("commonJvmArgs", {
  return [
   "-ea",
   "-Didea.home.path=$home",
   "-Xbootclasspath/p:${projectBuilder.moduleOutput(findModule("boot"))}",
   "-XX:+HeapDumpOnOutOfMemoryError",
   "-Didea.system.path=${p("teamcity.build.tempDir")}/system",
   "-Didea.config.path=${p("teamcity.build.tempDir")}/config",
   "-Xdebug",
   "-Xrunjdwp:transport=dt_socket,server=y,suspend=$suspendUntilDebuggerConnect,address=$debugPort"]
})

binding.setVariable("classPathLibs", [
        "bootstrap.jar",
        "extensions.jar",
        "util.jar",
        "jdom.jar",
        "log4j.jar",
        "trove4j.jar",
        "jna.jar"
])

binding.setVariable("platformApiModules", [
  "analysis-api",
  "core-api",
  "editor-ui-api",
  "external-system-api",
  "indexing-api",
  "jps-model-api",
  "lang-api",
  "lvcs-api",
  "projectModel-api",
  "platform-api",
  "structure-view-api",
  "usageView",
  "vcs-api",
  "vcs-log-api",
  "xdebugger-api",
  "xml-analysis-api",
  "xml-openapi",
  "xml-psi-api",
  "xml-structure-view-api",
])


binding.setVariable("platformImplementationModules", [
  "analysis-impl",
  "core-impl",
  "dvcs",
  "editor-ui-ex",
  "images",
  "indexing-impl",
  "jps-model-impl",
  "jps-model-serialization",
  "lang-impl",
  "lvcs-impl",
  "projectModel-impl",
  "platform-impl",
  "structure-view-impl",
  "vcs-impl",
  "vcs-log-graph",
  "vcs-log-impl",
  "testRunner",
  "smRunner",
  "relaxng",
  "RegExpSupport",
  "spellchecker",
  "xdebugger-impl",
  "xml",
  "xml-analysis-impl",
  "xml-psi-impl",
  "xml-structure-view-impl",
  "protocol-reader-runtime",
  "script-debugger-backend",
  "script-debugger-ui"
])

binding.setVariable("layoutMacApp", { String path, String ch, Map args ->
  ant.copy(todir: "$path/bin") {
    fileset(dir: "$ch/bin/mac")
  }

  ant.copy(todir: path) {
    fileset(dir: "$ch/build/conf/mac/Contents")
  }

  ant.tstamp() {
    format(property: "todayYear", pattern: "yyyy")
  }

  String executable = args.executable != null ? args.executable : p("component.names.product").toLowerCase()
  String helpId = args.help_id != null ? args.help_id : "IJ"
  String icns = "idea.icns"
  String helpIcns = "$path/Resources/${helpId}.help/Contents/Resources/Shared/product.icns"
  if (args.icns != null) {
    ant.delete(file: "$path/Resources/idea.icns")
    ant.copy(file: args.icns, todir: "$path/Resources")
    ant.copy(file: args.icns, tofile: helpIcns)
    icns = new File((String)args.icns).getName();
  } else {
    ant.copy(file: "$path/Resources/idea.icns", tofile: helpIcns)
  }

  String fullName = args.fullName != null ? args.fullName : p("component.names.fullname")

  String vmOptions = "-Dfile.encoding=UTF-8 ${vmOptions()} -Xverify:none"
  if (isEap() && !args.mac_no_yjp) {
    vmOptions += " ${yjpOptions(args.system_selector)}"
  }

  String minor = p("component.version.minor")
  String version = isEap() && !minor.contains("RC") && !minor.contains("Beta") ? "EAP $args.buildNumber" : "${p("component.version.major")}.${minor}"

  Map properties = readIdeaProperties(args)

  def coreKeys = ["idea.platform.prefix", "idea.paths.selector"]

  String coreProperties = submapToXml(properties, coreKeys);

  StringBuilder effectiveProperties = new StringBuilder()
  properties.each { k, v ->
    if (!coreKeys.contains(k)) {
      effectiveProperties.append("$k=$v\n");
    }
  }

  new File("$path/bin/idea.properties").text = effectiveProperties.toString()
  new File("$path/bin/idea.vmoptions").text = "$mem64 -XX:+UseCompressedOops".split(" ").join("\n")

  String classPath = classPathLibs.collect {"\$APP_PACKAGE/Contents/lib/${it}" }.join(":")

  String archs = """
    <key>LSArchitecturePriority</key>
    <array>"""
  (args.archs != null ? args.archs : ["x86_64", "i386"]).each {
    archs += "<string>${it}</string>"
  }
  archs +="</array>\n"
  
  String urlSchemes = ""
  if (args.urlSchemes != null) {
    urlSchemes += """
      <key>CFBundleURLTypes</key>
      <array>
        <dict>
          <key>CFBundleTypeRole</key>
          <string>Editor</string>
          <key>CFBundleURLName</key>
          <string>Stacktrace</string>
          <key>CFBundleURLSchemes</key>
          <array>
"""
    args.urlSchemes.each { scheme ->
      urlSchemes += "            <string>${scheme}</string>"
    }
    urlSchemes += """
          </array>
        </dict>
      </array>
"""
  }

  ant.replace(file: "$path/Info.plist") {
    replacefilter(token: "@@build@@", value: args.buildNumber)
    replacefilter(token: "@@doc_types@@", value: ifNull(args.doc_types, ""))
    replacefilter(token: "@@executable@@", value: executable)
    replacefilter(token: "@@icns@@", value: icns)
    replacefilter(token: "@@bundle_name@@", value: fullName)
    replacefilter(token: "@@bundle_identifier@@", value: args.bundleIdentifier)
    replacefilter(token: "@@year@@", value: "$todayYear")
    replacefilter(token: "@@version@@", value: version)
    replacefilter(token: "@@vmoptions@@", value: vmOptions)
    replacefilter(token: "@@idea_properties@@", value: coreProperties)
    replacefilter(token: "@@class_path@@", value: classPath)
    replacefilter(token: "@@help_id@@", value: helpId)
    replacefilter(token: "@@url_schemes@@", value: urlSchemes)
    replacefilter(token: "@@archs@@", value: archs)
  }

  if (executable != "idea") {
    ant.move(file: "$path/MacOS/idea", tofile: "$path/MacOS/$executable")
  }

  ant.replace(file: "$path/bin/inspect.sh") {
    replacefilter(token: "@@product_full@@", value: fullName)
    replacefilter(token: "@@script_name@@", value: executable)
  }
  if (args.inspect_script != null && args.inspect_script != "inspect") {
    ant.move(file: "$path/bin/inspect.sh", tofile: "$path/bin/${args.inspect_script}.sh")
  }

  ant.fixcrlf(srcdir: "$path/bin", includes: "*.sh", eol: "unix")
})

binding.setVariable("winScripts", { String target, String home, String name, Map args ->
  String fullName = args.fullName != null ? args.fullName : p("component.names.fullname")
  String product_uc = args.product_uc != null ? args.product_uc : p("component.names.product").toUpperCase()
  String vm_options = args.vm_options != null ? args.vm_options : "${p("component.names.product").toLowerCase()}.exe"
  if (vm_options.endsWith(".exe")) {
    vm_options = vm_options.replace(".exe", "%BITS%.exe")
  }
  else {
    vm_options = vm_options + "%BITS%"
  }

  String classPath = "SET CLASS_PATH=%IDE_HOME%\\lib\\${classPathLibs[0]}\n"
  classPath += classPathLibs[1..-1].collect {"SET CLASS_PATH=%CLASS_PATH%;%IDE_HOME%\\lib\\${it}"}.join("\n")
  if (args.tools_jar) classPath += "\nSET CLASS_PATH=%CLASS_PATH%;%JDK%\\lib\\tools.jar"

  ant.copy(todir: "$target/bin") {
    fileset(dir: "$home/bin/scripts/win")

    filterset(begintoken: "@@", endtoken: "@@") {
      filter(token: "product_full", value: fullName)
      filter(token: "product_uc", value: product_uc)
      filter(token: "vm_options", value: vm_options)
      filter(token: "isEap", value: isEap())
      filter(token: "system_selector", value: args.system_selector)
      filter(token: "ide_jvm_args", value: ifNull(args.ide_jvm_args, ""))
      filter(token: "class_path", value: classPath)
      filter(token: "script_name", value: name)
    }
  }

  if (name != "idea.bat") {
    ant.move(file: "$target/bin/idea.bat", tofile: "$target/bin/$name")
  }
  if (args.inspect_script != null && args.inspect_script != "inspect") {
    ant.move(file: "$target/bin/inspect.bat", tofile: "$target/bin/${args.inspect_script}.bat")
  }

  ant.fixcrlf(srcdir: "$target/bin", includes: "*.bat", eol: "dos")
})

private ifNull(v, defVal) { v != null ? v : defVal }

binding.setVariable("unixScripts", { String target, String home, String name, Map args ->
  String fullName = args.fullName != null ? args.fullName : p("component.names.fullname")
  String product_uc = args.product_uc != null ? args.product_uc : p("component.names.product").toUpperCase()
  String vm_options = args.vm_options != null ? args.vm_options : p("component.names.product").toLowerCase()

  String classPath = "CLASSPATH=\"\$IDE_HOME/lib/${classPathLibs[0]}\"\n"
  classPath += classPathLibs[1..-1].collect {"CLASSPATH=\"\$CLASSPATH:\$IDE_HOME/lib/${it}\""}.join("\n")
  if (args.tools_jar) classPath += "\nCLASSPATH=\"\$CLASSPATH:\$JDK/lib/tools.jar\""

  ant.copy(todir: "$target/bin") {
    fileset(dir: "$home/bin/scripts/unix")

    filterset(begintoken: "@@", endtoken: "@@") {
      filter(token: "product_full", value: fullName)
      filter(token: "product_uc", value: product_uc)
      filter(token: "vm_options", value: vm_options)
      filter(token: "isEap", value: isEap())
      filter(token: "system_selector", value: args.system_selector)
      filter(token: "ide_jvm_args", value: ifNull(args.ide_jvm_args, ""))
      filter(token: "class_path", value: classPath)
      filter(token: "script_name", value: name)
    }
  }

  if (name != "idea.sh") {
    ant.move(file: "$target/bin/idea.sh", tofile: "$target/bin/$name")
  }
  if (args.inspect_script != null && args.inspect_script != "inspect") {
    ant.move(file: "$target/bin/inspect.sh", tofile: "$target/bin/${args.inspect_script}.sh")
  }

  ant.fixcrlf(srcdir: "$target/bin", includes: "*.sh", eol: "unix")
})

binding.setVariable("winVMOptions", { String target, String system_selector, String name, String name64 = null ->
  if (name != null) {
    def options = isEap() && system_selector != null ? vmOptions32yjp(system_selector) : vmOptions32()
    ant.echo(file: "$target/bin/${name}.vmoptions", message: options.replace(' ', '\n'))
  }

  if (name64 != null) {
    def options = isEap() && system_selector != null ? vmOptions64yjp(system_selector) : vmOptions64()
    ant.echo(file: "$target/bin/${name64}.vmoptions", message: options.replace(' ', '\n'))
  }

  ant.fixcrlf(srcdir: "$target/bin", includes: "*.vmoptions", eol: "dos")
})

binding.setVariable("unixVMOptions", { String target, String name, String name64 = (name + "64") ->
  if (name != null) {
    ant.echo(file: "$target/bin/${name}.vmoptions", message: "${vmOptions32()} -Dawt.useSystemAAFontSettings=lcd".trim().replace(' ', '\n'))
  }
  if (name64 != null) {
    ant.echo(file: "$target/bin/${name64}.vmoptions", message: "${vmOptions64()} -Dawt.useSystemAAFontSettings=lcd".trim().replace(' ', '\n'))
  }
  ant.fixcrlf(srcdir: "$target/bin", includes: "*.vmoptions", eol: "unix")
})

binding.setVariable("unixReadme", { String target, String home, Map args ->
  String fullName = args.fullName != null ? args.fullName : p("component.names.fullname")
  String settings_dir = args.system_selector.replaceFirst("\\d+", "")
  copyAndPatchFile("$home/build/Install-Linux-tar.txt", "$target/Install-Linux-tar.txt",
                   ["product_full": fullName,
                    "product": p("component.names.product").toLowerCase(),
                    "system_selector": args.system_selector,
                    "settings_dir": settings_dir], "@@")
  ant.fixcrlf(file: "$target/bin/Install-Linux-tar.txt", eol: "unix")
})

binding.setVariable("forceDelete", { String dirPath ->
  // if wasn't deleted - retry several times
  attempt = 1
  while (attempt < 21 && (new File(dirPath).exists())) {
    if (attempt > 1) {
      ant.echo "Deleting $dirPath ... (attempt=$attempt)"

      // let's wait a bit and try again - may be help
      // in some cases on our windows 7 agents
      sleep(2000)
    }

    ant.delete(failonerror: false, dir: dirPath)

    attempt++
  }

  if (new File(dirPath).exists()) {
    ant.project.log ("Cannot delete directory: $dirPath" )
    System.exit (1)
  }
})

binding.setVariable("patchPropertiesFile", { String target, Map args = [:] ->
  String file = "$target/bin/idea.properties"

  if (args.appendices != null) {
    ant.concat(destfile: file, append:  true) {
      args.appendices.each {
        fileset(file: it)
      }
    }
  }

  String product_uc = args.product_uc != null ? args.product_uc : p("component.names.product").toUpperCase()
  String settings_dir = args.system_selector.replaceFirst("\\d+", "")
  ant.replace(file: file) {
    replacefilter(token: "@@product_uc@@", value: product_uc)
    replacefilter(token: "@@settings_dir@@", value: settings_dir)
  }

  String message = (isEap() ? """
#-----------------------------------------------------------------------
# Change to 'disabled' if you don't want to receive instant visual notifications
# about fatal errors that happen to an IDE or plugins installed.
#-----------------------------------------------------------------------
idea.fatal.error.notification=enabled
"""
                 : """
#-----------------------------------------------------------------------
# Change to 'enabled' if you want to receive instant visual notifications
# about fatal errors that happen to an IDE or plugins installed.
#-----------------------------------------------------------------------
idea.fatal.error.notification=disabled
""")
  ant.echo(file: file, append: true, message: message)
})

binding.setVariable("zipSources", { String home, String targetDir ->
  String sources = "$targetDir/sources.zip"
  projectBuilder.stage("zip sources to $sources")

  ant.mkdir(dir: targetDir)
  ant.delete(file: sources)
  ant.zip(destfile: sources) {
    fileset(dir: home) {
      ["java", "groovy", "ipr", "iml", "form", "xml", "properties"].each {
        include(name: "**/*.$it")
      }
      exclude(name: "**/testData/**")
    }
  }

  notifyArtifactBuilt(sources)
})

/**
 * E.g.
 *
 * Load all properties from file:
 *    readIdeaProperties("idea.properties.path" : "$home/ruby/build/idea.properties")
 *
 * Load all properties except "idea.cycle.buffer.size", change "idea.max.intellisense.filesize" to 3000
 * and enable "idea.is.internal" mode:
 *    readIdeaProperties("idea.properties.path" : "$home/ruby/build/idea.properties",
 *                       "idea.properties" : ["idea.max.intellisense.filesize" : 3000,
 *                                           "idea.cycle.buffer.size" : null,
 *                                           "idea.is.internal" : true ])
 * @param args
 * @return text xml properties description in xml
 */
private Map readIdeaProperties(Map args) {
  String ideaPropertiesPath =  args == null ? null : args.get("idea.properties.path")
  if (ideaPropertiesPath == null) {
    return [:]
  }

  // read idea.properties file
  Properties ideaProperties = new Properties();
  FileInputStream ideaPropertiesFile = new FileInputStream(ideaPropertiesPath);
  ideaProperties.load(ideaPropertiesFile);
  ideaPropertiesFile.close();

  def defaultProperties = ["CVS_PASSFILE": "~/.cvspass",
                           "com.apple.mrj.application.live-resize": "false",
                           "idea.paths.selector": args.system_selector,
                           "java.endorsed.dirs": "",
                           "idea.smooth.progress": "false",
                           "apple.laf.useScreenMenuBar": "true",
                           "apple.awt.graphics.UseQuartz": "true",
                           "apple.awt.fullscreencapturealldisplays": "false"]
  if (args.platform_prefix != null) {
    defaultProperties.put("idea.platform.prefix", args.platform_prefix)
  }

  Map properties = defaultProperties
  def customProperties = args.get("idea.properties")
  if (customProperties != null) {
    properties += customProperties
  }

  properties.each {k, v ->
    if (v == null) {
      // if overridden with null - ignore property
      ideaProperties.remove(k)
    } else {
      // if property is overridden in args map - use new value
      ideaProperties.put(k, v)
    }
  }

  return ideaProperties;
}

private String submapToXml(Map properties, List keys) {
// generate properties description for Info.plist
  StringBuilder buff = new StringBuilder()

  keys.each { key ->
    String value = properties[key]
    if (value != null) {
      String string =
        """
        <key>$key</key>
        <string>$value</string>
"""
      buff.append(string)
    }
  }
  return buff.toString()
}

binding.setVariable("buildWinZip", { String zipPath, List paths ->
  projectBuilder.stage(".win.zip")

  fixIdeaPropertiesEol(paths, "dos")

  ant.zip(zipfile: zipPath) {
    paths.each {
      fileset(dir: it)
    }
  }

  notifyArtifactBuilt(zipPath)
})

binding.setVariable("buildMacZip", { String zipRoot, String zipPath, List paths, String macPath, List extraBins = [] ->
  projectBuilder.stage(".mac.zip")

  allPaths = paths + [macPath]
  ant.zip(zipfile: zipPath) {
    allPaths.each {
      zipfileset(dir: it, prefix: zipRoot) {
        exclude(name: "bin/*.sh")
        exclude(name: "bin/*.py")
        exclude(name: "bin/fsnotifier")
        exclude(name: "bin/restarter")
        exclude(name: "MacOS/*")
        extraBins.each {
          exclude(name: it)
        }
        exclude(name: "bin/idea.properties")
      }
    }

    allPaths.each {
      zipfileset(dir: it, filemode: "755", prefix: zipRoot) {
        include(name: "bin/*.sh")
        include(name: "bin/*.py")
        include(name: "bin/fsnotifier")
        include(name: "bin/restarter")
        include(name: "MacOS/*")
        extraBins.each {
          include(name: it)
        }
      }
    }

    zipfileset(file: "$macPath/bin/idea.properties", prefix: "$zipRoot/bin")
  }
})

binding.setVariable("buildTarGz", { String tarRoot, String tarPath, List paths, List extraBins = [] ->
  projectBuilder.stage(".tar.gz")

  fixIdeaPropertiesEol(paths, "unix")

  ant.tar(tarfile: tarPath, longfile: "gnu") {
    paths.each {
      tarfileset(dir: it, prefix: tarRoot) {
        exclude(name: "bin/*.sh")
        exclude(name: "bin/fsnotifier*")
        extraBins.each {
          exclude(name: it)
        }
        type(type: "file")
      }
    }

    paths.each {
      tarfileset(dir: it, filemode: "755", prefix: tarRoot) {
        include(name: "bin/*.sh")
        include(name: "bin/fsnotifier*")
        extraBins.each {
          include(name: it)
        }
        type(type: "file")
      }
    }
  }

  String gzPath = "${tarPath}.gz"
  ant.gzip(src: tarPath, zipfile: gzPath)
  ant.delete(file: tarPath)
  notifyArtifactBuilt(gzPath)
})

private void fixIdeaPropertiesEol(List paths, String eol) {
  paths.each {
    String file = "$it/bin/idea.properties"
    if (new File(file).exists()) {
      ant.fixcrlf(file: file, eol: eol)
    }
  }
}

binding.setVariable("buildWinLauncher", { String ch, String inputPath, String outputPath, String appInfo,
                                          String launcherProperties, String pathsSelector, List resourcePaths ->
  projectBuilder.stage("winLauncher")

  if (pathsSelector != null) {
    def paths = getProperty("paths")
    def launcherPropertiesTemp = "${paths.sandbox}/launcher.properties"
    copyAndPatchFile(launcherProperties, launcherPropertiesTemp, ["PRODUCT_PATHS_SELECTOR": pathsSelector])
    launcherProperties = launcherPropertiesTemp
  }

  ant.java(classname: "com.pme.launcher.LauncherGeneratorMain", fork: "true") {
    sysproperty(key: "java.awt.headless", value: "true")
    arg(value: inputPath)
    arg(value: appInfo)
    arg(value: "$ch/native/WinLauncher/WinLauncher/resource.h")
    arg(value: launcherProperties)
    arg(value: outputPath)
    classpath {
      pathelement(location: "$ch/build/lib/launcher-generator.jar")
      fileset(dir: "$ch/lib") {
        include(name: "guava*.jar")
        include(name: "jdom.jar")
        include(name: "sanselan*.jar")
      }
      resourcePaths.each {
        pathelement(location: it)
      }
    }
  }
})

binding.setVariable("collectUsedJars", { List modules, List approvedJars, List forbiddenJars, List modulesToBuild ->
  def usedJars = new HashSet();

  modules.each {
    def module = findModule(it)
    if (module != null) {
      projectBuilder.moduleRuntimeClasspath(module, false).each {
        File file = new File(it)
        if (file.exists()) {
          String path = file.canonicalPath.replace('\\', '/')
          if (path.endsWith(".jar") && approvedJars.any { path.startsWith(it) } && !forbiddenJars.any { path.contains(it) }) {
            if (usedJars.add(path)) {
              projectBuilder.info("\tADDED: $path for ${module.getName()}")
            }
          }
        }
      }
      if (modulesToBuild != null) {
        modulesToBuild << module
      }
    }
    else {
      projectBuilder.warning("$it is not a module")
    }
  }

  return usedJars
})

binding.setVariable("buildModulesAndCollectUsedJars", { List modules, List approvedJars, List forbiddenJars ->
  def modulesToBuild = []
  def usedJars = collectUsedJars(modules, approvedJars, forbiddenJars, modulesToBuild)
  projectBuilder.cleanOutput()
  projectBuilder.buildModules(modulesToBuild)

  return usedJars
})

binding.setVariable("buildSearchableOptions", { String target, List licenses, Closure cp, String jvmArgs = null,
                                                def paths = getProperty("paths") ->
  projectBuilder.stage("Building searchable options")

  String targetFile = "${target}/searchableOptions.xml"
  ant.delete(file: targetFile)

  licenses.each {
    ant.copy(file: it, todir: paths.ideaSystem)
  }

  ant.path(id: "searchable.options.classpath") { cp() }
  String classpathFile = "${paths.sandbox}/classpath.txt"
  ant.echo(file: classpathFile, append: false, message: "\${toString:searchable.options.classpath}")
  ant.replace(file: classpathFile, token: File.pathSeparator, value: "\n")

  ant.java(classname: "com.intellij.rt.execution.CommandLineWrapper", fork: true, failonerror: true) {
    jvmarg(line: "-Xbootclasspath/a:${projectBuilder.moduleOutput(findModule("boot"))} -ea -Xmx500m -XX:MaxPermSize=200m")
    jvmarg(line: "-Didea.home.path=$home -Didea.system.path=${paths.ideaSystem} -Didea.config.path=${paths.ideaConfig}")
    if (jvmArgs != null) {
      jvmarg(line: jvmArgs)
    }

    arg(line: "${classpathFile} com.intellij.idea.Main traverseUI ${target}/searchableOptions.xml")

    classpath() {
      pathelement(location: "${projectBuilder.moduleOutput(findModule("java-runtime"))}")
    }
  }

  ant.available(file: targetFile, property: "searchable.options.exists");
  ant.fail(unless: "searchable.options.exists", message: "Searchable options were not built.")
})

binding.setVariable("reassignAltClickToMultipleCarets", {String communityHome ->
  String defaultKeymapContent = new File("$communityHome/platform/platform-resources/src/idea/Keymap_Default.xml").text
  defaultKeymapContent = defaultKeymapContent.replace("<mouse-shortcut keystroke=\"alt button1\"/>", "")
  defaultKeymapContent = defaultKeymapContent.replace("<mouse-shortcut keystroke=\"alt shift button1\"/>",
                                                      "<mouse-shortcut keystroke=\"alt button1\"/>")
  patchedKeymapFile = new File("${paths.sandbox}/classes/production/platform-resources/idea/Keymap_Default.xml")
  patchedKeymapFile.write(defaultKeymapContent)
})
