WIP daemon facade api, daemon client api
diff --git a/compiler/daemon/daemon-client/src/org/jetbrains/kotlin/daemon/client/KotlinDaemonClient.kt b/compiler/daemon/daemon-client/src/org/jetbrains/kotlin/daemon/client/KotlinDaemonClient.kt
new file mode 100644
index 0000000..18f83a56
--- /dev/null
+++ b/compiler/daemon/daemon-client/src/org/jetbrains/kotlin/daemon/client/KotlinDaemonClient.kt
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+/*
+ * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlin.daemon.client
+
+import org.jetbrains.kotlin.cli.common.ExitCode
+import org.jetbrains.kotlin.daemon.common.CompilationOptions
+import java.io.File
+
+typealias DaemonId = Int
+
+sealed class KotlinDaemonClient {
+    abstract fun compile(options: CompilationOptions, compilerArguments: List<String>/*, progressListener: ProgressListener?*/): ExitCode
+
+    abstract fun getAvailableDaemons(): List<DaemonId>
+
+    abstract fun getDaemonInfo(daemonId: DaemonId)
+
+    abstract fun stopDaemon(daemonId: DaemonId)
+}
+
+sealed interface KotlinDaemonClientProtocol<T : ProtocolSettings> {
+    object Rmi : KotlinDaemonClientProtocol<ProtocolSettings.RmiSettings>
+    object Http : KotlinDaemonClientProtocol<ProtocolSettings.HttpSettings>
+}
+
+class DaemonSettings<T : ProtocolSettings>(
+    val compilerClasspath: List<File>,
+    val jvmArgs: List<String>,
+    val protocol: KotlinDaemonClientProtocol<T>,
+    val protocolSettings: T
+)
+
+sealed interface ProtocolSettings {
+    class RmiSettings() : ProtocolSettings
+    class HttpSettings(/*host: String, port: Int*/) : ProtocolSettings
+}
+
+// TODO: think more about this interface
+internal class RmiKotlinDaemonClient(val daemonSettings: DaemonSettings<ProtocolSettings.RmiSettings>) : KotlinDaemonClient() {
+    override fun compile(options: CompilationOptions, compilerArguments: List<String>): ExitCode {
+        return ExitCode.OK
+    }
+
+    override fun getAvailableDaemons(): List<DaemonId> {
+        TODO("Not yet implemented")
+    }
+
+    override fun getDaemonInfo(daemonId: DaemonId) {
+        TODO("Not yet implemented")
+    }
+
+    override fun stopDaemon(daemonId: DaemonId) {
+        TODO("Not yet implemented")
+    }
+}
+
+internal class HttpKotlinDaemonClient(val daemonSettings: DaemonSettings<ProtocolSettings.HttpSettings>) : KotlinDaemonClient() {
+    override fun compile(options: CompilationOptions, compilerArguments: List<String>): ExitCode {
+        TODO("Not yet implemented")
+    }
+
+    override fun getAvailableDaemons(): List<DaemonId> {
+        TODO("Not yet implemented")
+    }
+
+    override fun getDaemonInfo(daemonId: DaemonId) {
+        TODO("Not yet implemented")
+    }
+
+    override fun stopDaemon(daemonId: DaemonId) {
+        TODO("Not yet implemented")
+    }
+}
+
+fun <T : ProtocolSettings> getKotlinDaemonClient(settings: DaemonSettings<T>) = when (settings.protocol) {
+    KotlinDaemonClientProtocol.Rmi -> RmiKotlinDaemonClient(settings as DaemonSettings<ProtocolSettings.RmiSettings>)
+    KotlinDaemonClientProtocol.Http -> HttpKotlinDaemonClient(settings as DaemonSettings<ProtocolSettings.HttpSettings>)
+}
\ No newline at end of file
diff --git a/compiler/daemon/daemon-facade/build.gradle.kts b/compiler/daemon/daemon-facade/build.gradle.kts
new file mode 100644
index 0000000..04e82a8
--- /dev/null
+++ b/compiler/daemon/daemon-facade/build.gradle.kts
@@ -0,0 +1,12 @@
+description = "Kotlin Daemon facade to unify running compilation via daemon, in-process, or out-of-process"
+
+plugins {
+    kotlin("jvm")
+}
+
+dependencies {
+    // todo think about dependency configurations
+    implementation(project(":kotlin-daemon-client"))
+    implementation(project(":daemon-common"))
+    implementation(project(":compiler:cli"))
+}
\ No newline at end of file
diff --git a/compiler/daemon/daemon-facade/src/main/kotlin/org/jetbrains/kotlin/facade/CompilerDaemonFacade.kt b/compiler/daemon/daemon-facade/src/main/kotlin/org/jetbrains/kotlin/facade/CompilerDaemonFacade.kt
new file mode 100644
index 0000000..b382209
--- /dev/null
+++ b/compiler/daemon/daemon-facade/src/main/kotlin/org/jetbrains/kotlin/facade/CompilerDaemonFacade.kt
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlin.facade
+
+import org.jetbrains.kotlin.cli.common.ExitCode
+import org.jetbrains.kotlin.daemon.client.DaemonSettings
+import org.jetbrains.kotlin.daemon.client.KotlinDaemonClient
+import org.jetbrains.kotlin.daemon.client.ProtocolSettings
+import org.jetbrains.kotlin.daemon.common.CompilationOptions
+import org.jetbrains.kotlin.facade.internal.DefaultCompilerDaemonFacade
+import java.io.File
+
+// TODO: think about progress reporting, metrics reporting, JPS integration problems?
+interface CompilerDaemonFacade {
+    fun <T : ProtocolSettings> getDaemonClient(
+        settings: DaemonSettings<T>
+    ): KotlinDaemonClient
+
+    // TODO: is this method needed?
+    /**
+     * Compile using Gradle daemon
+     */
+    fun <T : ProtocolSettings> compileWithDaemon(
+        settings: DaemonSettings<T>,
+        options: CompilationOptions,
+        compilerArguments: List<String>,
+    ): ExitCode
+
+    /**
+     * Compile invoking Kotlin compiler in the same process
+     */
+    fun compileInProcess(
+        options: CompilationOptions,
+        compilerArguments: List<String>,
+    ): ExitCode
+
+    /**
+     * Compile invoking Kotlin compiler in a separate process (each compilation runs inside separate process)
+     */
+    fun compileOutOfProcess(
+        settings: OutOfProcessCompilationSettings,
+        options: CompilationOptions,
+        compilerArguments: List<String>
+    ): ExitCode
+}
+
+class OutOfProcessCompilationSettings(
+    val compilerClasspath: List<File>,
+    val jvmArgs: List<String>,
+)
+
+fun getCompilerDaemonFacade(): CompilerDaemonFacade = DefaultCompilerDaemonFacade()
\ No newline at end of file
diff --git a/compiler/daemon/daemon-facade/src/main/kotlin/org/jetbrains/kotlin/facade/internal/DefaultCompilerDaemonFacade.kt b/compiler/daemon/daemon-facade/src/main/kotlin/org/jetbrains/kotlin/facade/internal/DefaultCompilerDaemonFacade.kt
new file mode 100644
index 0000000..9268739
--- /dev/null
+++ b/compiler/daemon/daemon-facade/src/main/kotlin/org/jetbrains/kotlin/facade/internal/DefaultCompilerDaemonFacade.kt
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlin.facade.internal
+
+import org.jetbrains.kotlin.cli.common.ExitCode
+import org.jetbrains.kotlin.daemon.client.DaemonSettings
+import org.jetbrains.kotlin.daemon.client.KotlinDaemonClient
+import org.jetbrains.kotlin.daemon.client.ProtocolSettings
+import org.jetbrains.kotlin.daemon.common.CompilationOptions
+import org.jetbrains.kotlin.facade.CompilerDaemonFacade
+import org.jetbrains.kotlin.facade.OutOfProcessCompilationSettings
+
+internal class DefaultCompilerDaemonFacade : CompilerDaemonFacade {
+    override fun <T : ProtocolSettings> getDaemonClient(settings: DaemonSettings<T>): KotlinDaemonClient {
+        TODO("Not yet implemented")
+    }
+
+    override fun <T : ProtocolSettings> compileWithDaemon(
+        settings: DaemonSettings<T>,
+        options: CompilationOptions,
+        compilerArguments: List<String>
+    ): ExitCode = getDaemonClient(settings).compile(options, compilerArguments)
+
+    override fun compileInProcess(options: CompilationOptions, compilerArguments: List<String>): ExitCode {
+        TODO("Not yet implemented")
+    }
+
+    override fun compileOutOfProcess(
+        settings: OutOfProcessCompilationSettings,
+        options: CompilationOptions,
+        compilerArguments: List<String>
+    ): ExitCode {
+        TODO("Not yet implemented")
+    }
+
+}
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerWork.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerWork.kt
index 5c82638..d5540ff1 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerWork.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerWork.kt
@@ -13,14 +13,16 @@
 import org.jetbrains.kotlin.cli.common.messages.MessageCollector
 import org.jetbrains.kotlin.cli.common.toBooleanLenient
 import org.jetbrains.kotlin.config.Services
+import org.jetbrains.kotlin.daemon.client.DaemonSettings
+import org.jetbrains.kotlin.daemon.client.KotlinDaemonClientProtocol
+import org.jetbrains.kotlin.daemon.client.ProtocolSettings
+import org.jetbrains.kotlin.daemon.client.getKotlinDaemonClient
 import org.jetbrains.kotlin.daemon.common.*
 import org.jetbrains.kotlin.gradle.logging.*
 import org.jetbrains.kotlin.gradle.plugin.internal.state.TaskExecutionResults
 import org.jetbrains.kotlin.gradle.plugin.internal.state.TaskLoggers
 import org.jetbrains.kotlin.gradle.report.*
-import org.jetbrains.kotlin.gradle.report.TaskExecutionInfo
 import org.jetbrains.kotlin.gradle.report.TaskExecutionProperties.ABI_SNAPSHOT
-import org.jetbrains.kotlin.gradle.report.TaskExecutionResult
 import org.jetbrains.kotlin.gradle.tasks.KotlinCompilerExecutionStrategy
 import org.jetbrains.kotlin.gradle.tasks.cleanOutputsAndLocalState
 import org.jetbrains.kotlin.gradle.tasks.throwGradleExceptionIfError
@@ -35,7 +37,6 @@
 import java.util.concurrent.Callable
 import java.util.concurrent.Executors
 import javax.inject.Inject
-import kotlin.collections.ArrayList
 
 internal class ProjectFilesForCompilation(
     val projectRootFile: File,
@@ -176,6 +177,32 @@
         }
     }
 
+    private fun compileWithDaemonNew(messageCollector: MessageCollector): ExitCode? {
+        val daemonClient = getKotlinDaemonClient(
+            DaemonSettings(
+                compilerClasspath = compilerFullClasspath,
+                jvmArgs = daemonJvmArgs ?: listOf(),
+                protocol = KotlinDaemonClientProtocol.Rmi,
+                protocolSettings = ProtocolSettings.RmiSettings()
+            )
+        )
+        val targetPlatform = when (compilerClassName) {
+            KotlinCompilerClass.JVM -> CompileService.TargetPlatform.JVM
+            KotlinCompilerClass.JS -> CompileService.TargetPlatform.JS
+            KotlinCompilerClass.METADATA -> CompileService.TargetPlatform.METADATA
+            else -> throw IllegalArgumentException("Unknown compiler type $compilerClassName")
+        }
+        val compilationOptions = CompilationOptions(
+            compilerMode = CompilerMode.NON_INCREMENTAL_COMPILER,
+            targetPlatform = targetPlatform,
+            reportCategories = reportCategories(isVerbose),
+            reportSeverity = reportSeverity(isVerbose),
+            requestedCompilationResults = emptyArray(),
+            kotlinScriptExtensions = kotlinScriptExtensions
+        )
+        return daemonClient.compile(compilationOptions, compilerArgs.toList())
+    }
+
     private fun compileWithDaemon(messageCollector: MessageCollector): ExitCode? {
         val isDebugEnabled = log.isDebugEnabled || System.getProperty("kotlin.daemon.debug.log")?.toBoolean() ?: true
         val daemonMessageCollector =
diff --git a/settings.gradle b/settings.gradle
index 5c2e5f3..22aef32 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -101,6 +101,7 @@
         ":kotlin-util-klib-metadata",
         ":daemon-common",
         ":daemon-common-new",
+        ":kotlin-daemon-facade",
         ":kotlin-daemon",
         ":kotlin-daemon-client",
         ":kotlin-daemon-client-new",
@@ -585,6 +586,7 @@
 project(':compiler:cli-js').projectDir = "$rootDir/compiler/cli/cli-js" as File
 project(':kotlin-runner').projectDir = "$rootDir/compiler/cli/cli-runner" as File
 project(':kotlin-daemon').projectDir = "$rootDir/compiler/daemon" as File
+project(':kotlin-daemon-facade').projectDir = "$rootDir/compiler/daemon/daemon-facade" as File
 project(':daemon-common').projectDir = "$rootDir/compiler/daemon/daemon-common" as File
 project(':daemon-common-new').projectDir = "$rootDir/compiler/daemon/daemon-common-new" as File
 project(':kotlin-daemon-client').projectDir = "$rootDir/compiler/daemon/daemon-client" as File