package ctbrec.io.json;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import ctbrec.Recording;
import ctbrec.io.json.dto.RecordingDto;
import org.json.JSONObject;
import org.junit.jupiter.api.Test;

import java.io.File;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Set;
import java.util.UUID;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

class ObjectMapperRecordingTest {

    @Test
    void recordingToJson() throws JsonProcessingException {
        RecordingDto rec = prepareRecording();

        ObjectMapper mapper = ObjectMapperFactory.getMapper();
        String json = mapper.writeValueAsString(rec);

        JSONObject j = new JSONObject(json);
        assertEquals(rec.getId(), j.getString("id"));
        assertEquals(rec.getStartDate().toEpochMilli(), j.getLong("startDate"));
        assertEquals(rec.getStatus().name(), j.getString("status"));
        assertEquals(rec.getProgress(), j.getInt("progress"));
        assertEquals(rec.getSizeInByte(), j.getLong("sizeInByte"));
        assertEquals(rec.getMetaDataFile(), j.getString("metaDataFile"));
        assertEquals(rec.isSingleFile(), j.getBoolean("singleFile"));
        assertEquals(rec.isPinned(), j.getBoolean("pinned"));
        assertEquals(rec.getNote(), j.getString("note"));
        assertTrue(j.getJSONArray("associatedFiles").toList().containsAll(Set.of("a", "b", "c")));
        assertEquals(rec.getAbsoluteFile().toString(), j.getString("absoluteFile"));
        assertEquals(rec.getPostProcessedFile().toString(), j.getString("postProcessedFile"));
        assertEquals(rec.getSelectedResolution(), j.getInt("selectedResolution"));
        assertEquals(rec.getLastSizeUpdate(), j.getLong("lastSizeUpdate"));
    }

    @Test
    void jsonToRecording() throws JsonProcessingException {
        RecordingDto rec = prepareRecording();
        ObjectMapper mapper = ObjectMapperFactory.getMapper();
        String json = mapper.writeValueAsString(rec);

        RecordingDto deserialized = mapper.readValue(json, RecordingDto.class);
        assertEquals(rec, deserialized);
    }

    private RecordingDto prepareRecording() {
        RecordingDto recording = new RecordingDto();
        recording.setId(UUID.randomUUID().toString());
        recording.setStartDate(Instant.now().truncatedTo(ChronoUnit.MILLIS));
        recording.setStatus(Recording.State.RECORDING);
        recording.setProgress(42);
        recording.setSizeInByte(23456789);
        recording.setMetaDataFile("/tmp/meta.json");
        recording.setSingleFile(true);
        recording.setPinned(true);
        recording.setNote("note");
        recording.setAssociatedFiles(Set.of("a", "b", "c"));
        recording.setAbsoluteFile(new File("/tmp/test.rec.ts"));
        recording.setPostProcessedFile(new File("/tmp/pp.ts"));
        recording.setSelectedResolution(2);
        recording.setLastSizeUpdate(Instant.now().toEpochMilli());
        return recording;
    }
}
