package com.securityc4po.api.pentest

import com.securityc4po.api.ResponseBody
import com.securityc4po.api.pentest.comment.Comment
import com.securityc4po.api.pentest.finding.Finding
import org.springframework.data.mongodb.core.index.Indexed
import java.util.UUID

data class Pentest(
    @Indexed(background = true, unique = true)
    val id: String = UUID.randomUUID().toString(),
    val projectId: String,
    val category: PentestCategory,
    val refNumber: String,
    val status: PentestStatus,
    var findingIds: List<String> = emptyList(),
    var commentIds: List<String> = emptyList()
)

fun buildPentest(body: PentestRequestBody, pentestEntity: PentestEntity): Pentest {
    return Pentest(
        id = pentestEntity.data.id,
        projectId = body.projectId,
        category = PentestCategory.valueOf(body.category),
        refNumber = body.refNumber,
        status = PentestStatus.valueOf(body.status),
        findingIds = body.findingIds,
        commentIds = body.commentIds
    )
}

/*fun addFindingToPentest(findingId: String, pentestEntity: PentestEntity): Pentest {
    return Pentest(
        id = pentestEntity.data.id,
        projectId = pentestEntity.data.projectId,
        category = pentestEntity.data.category,
        refNumber = pentestEntity.data.refNumber,
        status = pentestEntity.data.status,
        findingIds = pentestEntity.data.findingIds,
        commentIds = pentestEntity.data.commentIds
    )
}*/

fun Pentest.toPentestResponseBody(): ResponseBody {
    return mapOf(
        "id" to id,
        "projectId" to projectId,
        "category" to category,
        "refNumber" to refNumber,
        "status" to status,
        "findingIds" to findingIds,
        "commentIds" to commentIds
    )
}

data class CompletedPentest(
    val id: String,
    val projectId: String,
    val category: PentestCategory,
    val refNumber: String,
    val status: PentestStatus,
    var findings: MutableList<Finding>,
    var comments: MutableList<Comment>
)

fun CompletedPentest.toCompletedPentestResponseBody(): ResponseBody {
    return mapOf(
        "id" to id,
        "projectId" to projectId,
        "category" to category,
        "refNumber" to refNumber,
        "status" to status,
        "findings" to findings,
        "comments" to comments
    )
}

data class PentestRequestBody(
    val projectId: String,
    val refNumber: String,
    val category: String,
    val status: String,
    val findingIds: List<String>,
    val commentIds: List<String>
)

/**
 * Validates if a [PentestRequestBody] is valid
 *
 * @return Boolean describing if the body is valid
 */
fun PentestRequestBody.isValid(): Boolean {
    return when {
        this.projectId.isBlank() -> false
        this.refNumber.isBlank() -> false
        this.category.isBlank() -> false
        this.status.isBlank() -> false
        else -> true
    }
}

fun PentestRequestBody.toPentest(): Pentest {
    return Pentest(
        id = UUID.randomUUID().toString(),
        projectId = this.projectId,
        category = PentestCategory.valueOf(this.category),
        refNumber = this.refNumber,
        status = PentestStatus.valueOf(this.status),
        findingIds = this.findingIds,
        commentIds = this.commentIds
    )
}
