<commit_before>package org.jetbrains.sbt
package project

import java.io.File
import java.net.URL
import java.util

import com.intellij.execution.configurations.SimpleJavaParameters
import com.intellij.openapi.application.{ApplicationManager, PathManager}
import com.intellij.openapi.externalSystem.model.ExternalSystemException
import com.intellij.openapi.externalSystem.util._
import com.intellij.openapi.externalSystem.{ExternalSystemConfigurableAware, ExternalSystemManager}
import com.intellij.openapi.options.Configurable
import com.intellij.openapi.project.Project
import com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl
import com.intellij.openapi.projectRoots.{JavaSdkType, ProjectJdkTable}
import com.intellij.openapi.roots.ProjectRootManager
import com.intellij.openapi.util.Pair
import com.intellij.testFramework.IdeaTestUtil
import com.intellij.util.Function
import com.intellij.util.net.HttpConfigurable
import org.jetbrains.android.sdk.AndroidSdkType
import org.jetbrains.sbt.project.settings._
import org.jetbrains.sbt.settings.{SbtExternalSystemConfigurable, SbtSystemSettings}

/**
 * @author <NAME>
 */
class SbtExternalSystemManager
  extends ExternalSystemManager[SbtProjectSettings, SbtProjectSettingsListener, SbtSystemSettings, SbtLocalSettings, SbtExecutionSettings]
  with ExternalSystemConfigurableAware {

  def enhanceLocalProcessing(urls: util.List[URL]) {
    urls.add(jarWith[scala.App].toURI.toURL)
  }

  def enhanceRemoteProcessing(parameters: SimpleJavaParameters) {
    val classpath = parameters.getClassPath

    classpath.add(jarWith[this.type])
    classpath.add(jarWith[org.jetbrains.sbt.structure.XmlSerializer[_]])
    classpath.add(jarWith[scala.App])
    classpath.add(jarWith[scala.xml.Node])

    parameters.getVMParametersList.addProperty(
      ExternalSystemConstants.EXTERNAL_SYSTEM_ID_KEY, SbtProjectSystem.Id.getId)

    parameters.getVMParametersList.addProperty(
      PathManager.PROPERTY_LOG_PATH, PathManager.getLogPath)
  }

  def getSystemId = SbtProjectSystem.Id

  def getSettingsProvider: Function[Project, SbtSystemSettings] = SbtSystemSettings.getInstance _

  def getLocalSettingsProvider: Function[Project, SbtLocalSettings] = SbtLocalSettings.getInstance _

  def getExecutionSettingsProvider: Function[Pair[Project, String], SbtExecutionSettings] = SbtExternalSystemManager.executionSettingsFor _

  def getProjectResolverClass: Class[SbtProjectResolver] = classOf[SbtProjectResolver]

  def getTaskManagerClass: Class[SbtTaskManager] = classOf[SbtTaskManager]

  def getExternalProjectDescriptor = new SbtOpenProjectDescriptor()

  def getConfigurable(project: Project): Configurable = new SbtExternalSystemConfigurable(project)
}

object SbtExternalSystemManager {
  def executionSettingsFor(project: Project, path: String): SbtExecutionSettings = {
    val settings = SbtSystemSettings.getInstance(project)
    val projectSettings = Option(settings.getLinkedProjectSettings(path)).getOrElse(SbtProjectSettings.default)

    val customLauncher = settings.customLauncherEnabled.option(settings.getCustomLauncherPath).map(_.toFile)
    val customSbtStructureFile = settings.customSbtStructurePath.nonEmpty.option(settings.customSbtStructurePath.toFile)

    val realProjectPath = Option(projectSettings.getExternalProjectPath).getOrElse(path)
    val projectJdkName = Option(ProjectRootManager.getInstance(project).getProjectSdk).map(_.getName)
    val vmExecutable = getVmExecutable(projectJdkName, settings)
    val vmOptions = getVmOptions(settings)
    val environment = Map.empty ++ getAndroidEnvironmentVariables(projectJdkName)

    new SbtExecutionSettings(realProjectPath,
      vmExecutable, vmOptions, environment, customLauncher, customSbtStructureFile, projectJdkName,
      projectSettings.resolveClassifiers, projectSettings.resolveJavadocs, projectSettings.resolveSbtClassifiers)
  }

  private def getVmExecutable(projectJdkName: Option[String], settings: SbtSystemSettings): File =
      if (!ApplicationManager.getApplication.isUnitTestMode)
        getRealVmExecutable(projectJdkName, settings)
      else
        getUnitTestVmExecutable

  private def getUnitTestVmExecutable: File = {
    val internalSdk = JavaAwareProjectJdkTableImpl.getInstanceEx.getInternalJdk
    val sdk = if (internalSdk == null) IdeaTestUtil.getMockJdk17 else internalSdk
    val sdkType = sdk.getSdkType.asInstanceOf[JavaSdkType]
    new File(sdkType.getVMExecutablePath(sdk))
  }

  private def getRealVmExecutable(projectJdkName: Option[String], settings: SbtSystemSettings): File = {
    val customVmFile = new File(settings.getCustomVMPath) / "bin" / "java"
    val customVmExecutable = settings.customVMEnabled.option(customVmFile)

    customVmExecutable.orElse {
      val projectSdk = projectJdkName.flatMap(name => Option(ProjectJdkTable.getInstance().findJdk(name)))
      projectSdk.map { sdk =>
        sdk.getSdkType match {
          case sdkType : JavaSdkType =>
            new File(sdkType.getVMExecutablePath(sdk))
          case _ =>
            throw new ExternalSystemException(SbtBundle("sbt.import.noProjectJvmFound"))
        }
      }
    } getOrElse {<commit_msg>Choose a default jdk when importing projects. Avoids error when no jdk is set in project defaults.<commit_after>package org.jetbrains.sbt
package project

import java.io.File
import java.net.URL
import java.util

import com.intellij.execution.configurations.SimpleJavaParameters
import com.intellij.openapi.application.{ApplicationManager, PathManager}
import com.intellij.openapi.externalSystem.model.ExternalSystemException
import com.intellij.openapi.externalSystem.util._
import com.intellij.openapi.externalSystem.{ExternalSystemConfigurableAware, ExternalSystemManager}
import com.intellij.openapi.options.Configurable
import com.intellij.openapi.project.Project
import com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl
import com.intellij.openapi.projectRoots.{JavaSdk, JavaSdkType, ProjectJdkTable}
import com.intellij.openapi.roots.ProjectRootManager
import com.intellij.openapi.util.Pair
import com.intellij.testFramework.IdeaTestUtil
import com.intellij.util.Function
import com.intellij.util.net.HttpConfigurable
import org.jetbrains.android.sdk.AndroidSdkType
import org.jetbrains.sbt.project.settings._
import org.jetbrains.sbt.settings.{SbtExternalSystemConfigurable, SbtSystemSettings}

/**
 * @author <NAME>
 */
class SbtExternalSystemManager
  extends ExternalSystemManager[SbtProjectSettings, SbtProjectSettingsListener, SbtSystemSettings, SbtLocalSettings, SbtExecutionSettings]
  with ExternalSystemConfigurableAware {

  def enhanceLocalProcessing(urls: util.List[URL]) {
    urls.add(jarWith[scala.App].toURI.toURL)
  }

  def enhanceRemoteProcessing(parameters: SimpleJavaParameters) {
    val classpath = parameters.getClassPath

    classpath.add(jarWith[this.type])
    classpath.add(jarWith[org.jetbrains.sbt.structure.XmlSerializer[_]])
    classpath.add(jarWith[scala.App])
    classpath.add(jarWith[scala.xml.Node])

    parameters.getVMParametersList.addProperty(
      ExternalSystemConstants.EXTERNAL_SYSTEM_ID_KEY, SbtProjectSystem.Id.getId)

    parameters.getVMParametersList.addProperty(
      PathManager.PROPERTY_LOG_PATH, PathManager.getLogPath)
  }

  def getSystemId = SbtProjectSystem.Id

  def getSettingsProvider: Function[Project, SbtSystemSettings] = SbtSystemSettings.getInstance _

  def getLocalSettingsProvider: Function[Project, SbtLocalSettings] = SbtLocalSettings.getInstance _

  def getExecutionSettingsProvider: Function[Pair[Project, String], SbtExecutionSettings] = SbtExternalSystemManager.executionSettingsFor _

  def getProjectResolverClass: Class[SbtProjectResolver] = classOf[SbtProjectResolver]

  def getTaskManagerClass: Class[SbtTaskManager] = classOf[SbtTaskManager]

  def getExternalProjectDescriptor = new SbtOpenProjectDescriptor()

  def getConfigurable(project: Project): Configurable = new SbtExternalSystemConfigurable(project)
}

object SbtExternalSystemManager {
  def executionSettingsFor(project: Project, path: String): SbtExecutionSettings = {
    val settings = SbtSystemSettings.getInstance(project)
    val projectSettings = Option(settings.getLinkedProjectSettings(path)).getOrElse(SbtProjectSettings.default)

    val customLauncher = settings.customLauncherEnabled.option(settings.getCustomLauncherPath).map(_.toFile)
    val customSbtStructureFile = settings.customSbtStructurePath.nonEmpty.option(settings.customSbtStructurePath.toFile)

    val realProjectPath = Option(projectSettings.getExternalProjectPath).getOrElse(path)
    val projectJdkName = Option(ProjectRootManager.getInstance(project).getProjectSdk).map(_.getName)
    val vmExecutable = getVmExecutable(projectJdkName, settings)
    val vmOptions = getVmOptions(settings)
    val environment = Map.empty ++ getAndroidEnvironmentVariables(projectJdkName)

    new SbtExecutionSettings(realProjectPath,
      vmExecutable, vmOptions, environment, customLauncher, customSbtStructureFile, projectJdkName,
      projectSettings.resolveClassifiers, projectSettings.resolveJavadocs, projectSettings.resolveSbtClassifiers)
  }

  private def getVmExecutable(projectJdkName: Option[String], settings: SbtSystemSettings): File =
      if (!ApplicationManager.getApplication.isUnitTestMode)
        getRealVmExecutable(projectJdkName, settings)
      else
        getUnitTestVmExecutable

  private def getUnitTestVmExecutable: File = {
    val internalSdk = JavaAwareProjectJdkTableImpl.getInstanceEx.getInternalJdk
    val sdk = if (internalSdk == null) IdeaTestUtil.getMockJdk17 else internalSdk
    val sdkType = sdk.getSdkType.asInstanceOf[JavaSdkType]
    new File(sdkType.getVMExecutablePath(sdk))
  }

  private def getRealVmExecutable(projectJdkName: Option[String], settings: SbtSystemSettings): File = {
    val customVmFile = new File(settings.getCustomVMPath) / "bin" / "java"
    val customVmExecutable = settings.customVMEnabled.option(customVmFile)
    val jdkType = JavaSdk.getInstance()

    customVmExecutable.orElse {
      projectJdkName
        .flatMap(name => Option(ProjectJdkTable.getInstance().findJdk(name)))
        .map { sdk =>
          if (sdk.getSdkType == jdkType)
            new File(jdkType.getVMExecutablePath(sdk))
          else
          throw new ExternalSystemException(SbtBundle("sbt.import.noProjectJvmFound"))
        }
    }
    .orElse {
      Option(ProjectJdkTable.getInstance().findMostRecentSdkOfType(jdkType))
        .map { sdk =>
          new File(jdkType.getVMExecutablePath(sdk))
        }
    }
    .getOrElse {
{'fraction_non_alphanumeric': 0.08113456464379948, 'fraction_numerical': 0.0003769317753486619, 'mean_word_length': 5.729866835764109, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 12, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4152123', 'n_tokens_mistral': 3157, 'n_tokens_neox': 3067, 'n_words': 489}