package com.correx.infrastructure.artifactscas.segment

import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.io.RandomAccessFile
import java.nio.file.Path

class CorruptRecordException(message: String) : RuntimeException(message)

class SegmentReader {
    suspend fun read(loc: Location, segmentsDir: Path): ByteArray = withContext(Dispatchers.IO) {
        val path = segmentsDir.resolve(SegmentWriter.segmentFileName(loc.segmentId))
        RandomAccessFile(path.toFile(), "r").use { raf ->
            raf.seek(loc.offset)
            val header = ByteArray(SegmentLayout.HEADER_SIZE)
            raf.readFully(header)
            val (length, crc, hash) = SegmentLayout.decodeHeader(header)
            if (length != loc.length) {
                throw CorruptRecordException("length mismatch at seg=${loc.segmentId} off=${loc.offset}")
            }
            val payload = ByteArray(length)
            raf.readFully(payload)
            if (SegmentLayout.crc32c(payload) != crc) {
                throw CorruptRecordException("crc mismatch at seg=${loc.segmentId} off=${loc.offset}")
            }
            if (!SegmentLayout.blake3(payload).contentEquals(hash)) {
                throw CorruptRecordException("hash mismatch at seg=${loc.segmentId} off=${loc.offset}")
            }
            payload
        }
    }
}
