package com.jaytux.simd.data

import com.jaytux.simd.data.CppType.Companion.optionalReferrersOn
import org.jetbrains.exposed.dao.*
import org.jetbrains.exposed.dao.id.CompositeID
import org.jetbrains.exposed.dao.id.EntityID
import java.util.*

class Tech(id: EntityID<UUID>) : UUIDEntity(id) {
    companion object : UUIDEntityClass<Tech>(Techs)

    var name by Techs.name
}

class CppType(id: EntityID<UUID>) : UUIDEntity(id) {
    companion object : UUIDEntityClass<CppType>(CppTypes)

    var name by CppTypes.name
}

class Category(id: EntityID<UUID>) : UUIDEntity(id) {
    companion object : UUIDEntityClass<Category>(Categories)

    var name by Categories.name
}

class CPUID(id: EntityID<UUID>) : UUIDEntity(id) {
    companion object : UUIDEntityClass<CPUID>(CPUIDs)

    var name by CPUIDs.name
}

class Intrinsic(id: EntityID<UUID>) : UUIDEntity(id) {
    companion object : UUIDEntityClass<Intrinsic>(Intrinsics)

    var mnemonic by Intrinsics.mnemonic
    var returnType by CppType referencedOn Intrinsics.returnType
    var returnVar by Intrinsics.returnVar
    var description by Intrinsics.description
    var operations by Intrinsics.operations
    var category by Category referencedOn Intrinsics.category
    var cpuid by CPUID optionalReferencedOn Intrinsics.cpuid
    var tech by Tech referencedOn Intrinsics.tech

    val arguments by IntrinsicArgument referrersOn IntrinsicArguments.intrinsic
    val instructions by IntrinsicInstruction referrersOn IntrinsicInstructions.intrinsic
}

class IntrinsicArgument(id: EntityID<UUID>) : UUIDEntity(id) {
    companion object : UUIDEntityClass<IntrinsicArgument>(IntrinsicArguments)

    var intrinsic by Intrinsic referencedOn IntrinsicArguments.intrinsic
    var name by IntrinsicArguments.name
    var type by CppType referencedOn IntrinsicArguments.type
    var index by IntrinsicArguments.index
}

class IntrinsicInstruction(id: EntityID<UUID>) : UUIDEntity(id) {
    companion object : UUIDEntityClass<IntrinsicInstruction>(IntrinsicInstructions)

    var intrinsic by Intrinsic referencedOn IntrinsicInstructions.intrinsic
    var mnemonic by IntrinsicInstructions.mnemonic
    var xed by IntrinsicInstructions.xed
    var form by IntrinsicInstructions.form

    val performance by Performance referrersOn Performances.instruction
}

class Platform(id: EntityID<UUID>) : UUIDEntity(id) {
    companion object : UUIDEntityClass<Platform>(Platforms)

    var name by Platforms.name
}

class Performance(id: EntityID<CompositeID>) : CompositeEntity(id) {
    companion object : CompositeEntityClass<Performance>(Performances)

    var instruction by IntrinsicInstruction referencedOn Performances.instruction
    var platform by Platform referencedOn Performances.platform
    var latency by Performances.latency
    var throughput by Performances.throughput
}