You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

105 lines
3.7 KiB

package net.aiterp.git.ykonsole2
import kotlinx.coroutines.runBlocking
import net.aiterp.git.ykonsole2.application.createServer
import net.aiterp.git.ykonsole2.application.env.optStrEnv
import net.aiterp.git.ykonsole2.application.env.strEnv
import net.aiterp.git.ykonsole2.application.services.DriverStarter
import net.aiterp.git.ykonsole2.domain.models.*
import net.aiterp.git.ykonsole2.domain.runtime.CommandBus
import net.aiterp.git.ykonsole2.domain.runtime.EventBus
import net.aiterp.git.ykonsole2.infrastructure.ExportTarget
import net.aiterp.git.ykonsole2.infrastructure.IConsole
import net.aiterp.git.ykonsole2.infrastructure.WorkoutExporter
import net.aiterp.git.ykonsole2.infrastructure.drivers.ProgramEnforcer
import net.aiterp.git.ykonsole2.infrastructure.drivers.Skipper
import net.aiterp.git.ykonsole2.infrastructure.drivers.WorkoutWriter
import net.aiterp.git.ykonsole2.infrastructure.indigo1.Indigo1
import net.aiterp.git.ykonsole2.infrastructure.makeDataSource
import net.aiterp.git.ykonsole2.infrastructure.repositories.deviceRepo
import net.aiterp.git.ykonsole2.infrastructure.repositories.programRepo
import net.aiterp.git.ykonsole2.infrastructure.repositories.workoutRepo
import net.aiterp.git.ykonsole2.infrastructure.repositories.workoutStateRepo
import net.aiterp.git.ykonsole2.infrastructure.testing.*
import kotlin.time.Duration.Companion.seconds
fun main(): Unit = runBlocking {
initRepositories().apply {
val commandBus = CommandBus()
val eventBus = EventBus()
workoutRepo.findActive()?.let { active ->
active.status = WorkoutStatus.Disconnected
workoutRepo.save(active)
}
val exporter = workoutExporterOrNull()
val iConsole = IConsole()
val programEnforcer = ProgramEnforcer(programRepo, workoutRepo)
val skipper = Skipper()
val testDriver = TestDriver(secondLength = 1.seconds)
val workoutWriter = WorkoutWriter(workoutRepo, workoutStateRepo)
createServer(
deviceRepo = deviceRepo,
programRepo = programRepo,
workoutRepo = workoutRepo,
workoutStateRepo = workoutStateRepo,
commandBus = commandBus,
eventBus = eventBus,
).start(wait = false)
DriverStarter(
drivers = listOfNotNull(
exporter,
iConsole,
programEnforcer,
skipper,
testDriver,
workoutWriter,
),
input = commandBus,
output = eventBus,
).startDrivers()
}
}
private fun initRepositories(): RepositorySet = when (val storageType = strEnv("STORAGE_TYPE")) {
"in_memory" -> RepositorySet(
deviceRepo = InMemoryDeviceRepository(),
programRepo = InMemoryProgramRepository(),
workoutRepo = InMemoryWorkoutRepository(),
workoutStateRepo = InMemoryWorkoutStateRepository(),
)
"mysql" -> makeDataSource(
url = strEnv("MYSQL_URL"),
username = strEnv("MYSQL_USERNAME"),
password = strEnv("MYSQL_PASSWORD"),
).run { RepositorySet(deviceRepo, programRepo, workoutRepo, workoutStateRepo) }
else -> error("Invalid storage type: $storageType")
}
private data class RepositorySet(
val deviceRepo: DeviceRepository,
val programRepo: ProgramRepository,
val workoutRepo: WorkoutRepository,
val workoutStateRepo: WorkoutStateRepository,
) {
fun workoutExporterOrNull(): WorkoutExporter? {
val exportTarget = makeExportTarget() ?: return null
return WorkoutExporter(workoutRepo, workoutStateRepo, deviceRepo, programRepo, exportTarget)
}
private fun makeExportTarget(): ExportTarget? {
val indigo1Endpoint = optStrEnv("INDIGO1_ENDPOINT")
if (indigo1Endpoint != null) {
val clientId = strEnv("INDIGO1_CLIENT_ID")
val clientSecret = strEnv("INDIGO1_CLIENT_SECRET")
return Indigo1(indigo1Endpoint, clientId, clientSecret)
}
return null
}
}