package com.jaytux.simd.server import com.jaytux.simd.data.* import io.ktor.http.content.* import io.ktor.server.response.* import io.ktor.server.routing.* import kotlinx.datetime.LocalDate import kotlinx.serialization.Serializable import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.jetbrains.exposed.sql.SqlExpressionBuilder.like import org.jetbrains.exposed.sql.selectAll import org.jetbrains.exposed.sql.transactions.transaction import java.util.* @Serializable data class IntrinsicSummary(@Serializable(with = UUIDSerializer::class) val id: UUID, val name: String) @Serializable data class Param(val name: String, val type: String) @Serializable data class Instruction(val mnemonic: String, val xed: String, val form: String?) @Serializable data class PlatformPerformance(val platform: String, val latency: Float?, val throughput: Float?) @Serializable data class IntrinsicDetails( @Serializable(with = UUIDSerializer::class) val id: UUID, val name: String, val returnType: String, val returnVar: String?, val description: String, val operations: String?, val category: String, val cpuid: String?, val tech: String, val params: List, val instructions: List?, val performance: List? ) @Serializable data class Versioning( val intelVersion: String, val intelUpdate: LocalDate, val scrapeDate: LocalDate ) fun Routing.installGetAll() { getPagedUrl("/all", { 100 }, { IntrinsicSummary(it.id.value, it.mnemonic) }) { Intrinsic.all().orderAsc(Intrinsics.mnemonic) } getPagedUrl("/cpuid", { 100 }, { it.name }) { CPUID.all().orderAsc(CPUIDs.name) } getPagedUrl("/tech", { 100 }, { it.name }) { Tech.all().orderAsc(Techs.name) } getPagedUrl("/category", { 100 }, { it.name }) { Category.all().orderAsc(Categories.name) } getPagedUrl("/types", { 100 }, { it.name }) { CppType.all().orderAsc(CppTypes.name) } } fun Routing.installSearch() { getPagedRequest("/search", { 100 }, { IntrinsicSummary(it[Intrinsics.id].value, it[Intrinsics.mnemonic]) }) { val name = call.request.queryParameters["name"] val returnType = call.request.queryParameters["return"]?.let { CppType.find { CppTypes.name eq it }.firstOrNull() ?: throw HttpError("Unknown return type: $it") } val cpuid = call.request.queryParameters["cpuid"]?.let { CPUID.find { CPUIDs.name eq it }.firstOrNull() ?: throw HttpError("Unknown CPUID: $it") } val tech = call.request.queryParameters["tech"]?.let { Tech.find { Techs.name eq it }.firstOrNull() ?: throw HttpError("Unknown tech: $it") } val category = call.request.queryParameters["category"]?.let { Category.find { Categories.name eq it }.firstOrNull() ?: throw HttpError("Unknown category: $it") } val desc = call.request.queryParameters["desc"] var results = Intrinsics.selectAll() name?.let { results = results.where { Intrinsics.mnemonic like "%$it%" } } returnType?.let { results = results.where { Intrinsics.returnType eq it.id } } cpuid?.let { results = results.where { Intrinsics.cpuid eq it.id } } tech?.let { results = results.where { Intrinsics.tech eq it.id } } category?.let { results = results.where { Intrinsics.category eq it.id } } desc?.let { results = results.where { Intrinsics.description like "%$it%" } } results.orderAsc(Intrinsics.mnemonic) } } fun Routing.installDetails() { get("/details/{id}") { runCatching { transaction { val id = call.parameters["id"]?.let { try { UUID.fromString(it) } catch(e: IllegalArgumentException) { throw HttpError("Invalid UUID: $it") } } ?: throw HttpError("Missing or invalid ID") val intrinsic = Intrinsic.findById(id) ?: throw HttpError("Unknown intrinsic: $id") IntrinsicDetails( id = intrinsic.id.value, name = intrinsic.mnemonic, returnType = intrinsic.returnType.name, returnVar = intrinsic.returnVar, description = intrinsic.description, operations = intrinsic.operations, category = intrinsic.category.name, cpuid = intrinsic.cpuid?.name, tech = intrinsic.tech.name, params = intrinsic.arguments.orderAsc(IntrinsicArguments.index) .map { Param(it.name, it.type.name) }, instructions = intrinsic.instructions.emptyToNull() ?.map { Instruction(it.mnemonic, it.xed, it.form) }, performance = intrinsic.instructions.firstOrNull()?.let { (Performances innerJoin Platforms).selectAll().where { Performances.instruction eq it.id }.map { PlatformPerformance( platform = it[Platforms.name], latency = it[Performances.latency], throughput = it[Performances.throughput] ) } } ) } } } } fun Routing.installVersion() { get("/version") { val upd = Loader.DatedVersion.fromPrefs() call.respond(Versioning(upd.version.toString(), intelUpdate = upd.releaseDate, upd.updateDate)) } }