package dev.inmo.postssystem.core.post

import dev.inmo.postssystem.core.UnixMillis
import dev.inmo.postssystem.core.content.ContentId
import com.soywiz.klock.DateTime
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient

typealias PostId = String
typealias ContentIds = List<ContentId>

/**
 * Base interface for creating of new post. Usually, it is just [SimplePost] instance
 */
@Serializable
sealed class Post {
    abstract val content: ContentIds
}

/**
 * Root entity of the whole system. Can be retrieved from [dev.inmo.postssystem.core.post.repo.ReadPostsRepo]
 * by getting and created in [dev.inmo.postssystem.core.post.repo.WritePostsRepo] by inserting of [Post]
 * instance
 */
@Serializable
sealed class RegisteredPost : Post() {
    abstract val id: PostId

    abstract override val content: ContentIds

    abstract val creationDate: DateTime
}

/**
 * Base and currently (1st Nov 2019) single realisation of [Post]. There is [SimpleRegisteredPost] which is technically
 * is [Post] too, but it is not direct [Post] realisation
 */
@Serializable
data class SimplePost(
    override val content: ContentIds
) : Post()

/**
 * Base and currently (1st Nov 2019) single realisation of [RegisteredPost]
 */
@Serializable
data class SimpleRegisteredPost(
    override val id: PostId,
    override val content: ContentIds,
    private val creationDateTimeMillis: UnixMillis
) : RegisteredPost() {
    @Transient
    override val creationDate: DateTime = DateTime(creationDateTimeMillis)
}

@Suppress("FunctionName")
fun RegisteredPost(
    id: PostId,
    content: ContentIds,
    creationDate: DateTime
) = SimpleRegisteredPost(id, content, creationDate.unixMillis)