package be.simplenotes.app.api import be.simplenotes.app.extensions.json import be.simplenotes.app.utils.parseSearchTerms import be.simplenotes.domain.model.PersistedNote import be.simplenotes.domain.model.PersistedNoteMetadata import be.simplenotes.domain.security.JwtPayload import be.simplenotes.domain.usecases.NoteService import kotlinx.serialization.Contextual import kotlinx.serialization.Serializable import kotlinx.serialization.builtins.ListSerializer import kotlinx.serialization.json.Json import org.http4k.core.Request import org.http4k.core.Response import org.http4k.core.Status.Companion.BAD_REQUEST import org.http4k.core.Status.Companion.NOT_FOUND import org.http4k.core.Status.Companion.OK import org.http4k.routing.path import java.util.* class ApiNoteController(private val noteService: NoteService, private val json: Json) { fun createNote(request: Request, jwtPayload: JwtPayload): Response { val content = json.decodeFromString(NoteContent.serializer(), request.bodyString()).content return noteService.create(jwtPayload.userId, content).fold( { Response(BAD_REQUEST) }, { Response(OK).json(json.encodeToString(UuidContent.serializer(), UuidContent(it.uuid))) } ) } fun notes(request: Request, jwtPayload: JwtPayload): Response { val notes = noteService.paginatedNotes(jwtPayload.userId, page = 1).notes val json = json.encodeToString(ListSerializer(PersistedNoteMetadata.serializer()), notes) return Response(OK).json(json) } fun note(request: Request, jwtPayload: JwtPayload): Response { val uuid = request.path("uuid")!! return noteService.find(jwtPayload.userId, UUID.fromString(uuid)) ?.let { Response(OK).json(json.encodeToString(PersistedNote.serializer(), it)) } ?: Response(NOT_FOUND) } fun update(request: Request, jwtPayload: JwtPayload): Response { val uuid = UUID.fromString(request.path("uuid")!!) val content = json.decodeFromString(NoteContent.serializer(), request.bodyString()).content return noteService.update(jwtPayload.userId, uuid, content).fold({ Response(BAD_REQUEST) }, { if (it == null) Response(NOT_FOUND) else Response(OK) }) } fun search(request: Request, jwtPayload: JwtPayload): Response { val query = json.decodeFromString(SearchContent.serializer(), request.bodyString()).query val terms = parseSearchTerms(query) val notes = noteService.search(jwtPayload.userId, terms) val json = json.encodeToString(ListSerializer(PersistedNoteMetadata.serializer()), notes) return Response(OK).json(json) } } @Serializable data class NoteContent(val content: String) @Serializable data class UuidContent(@Contextual val uuid: UUID) @Serializable data class SearchContent(@Contextual val query: String)