package ctbrec.recorder.postprocessing;

import static org.junit.Assert.*;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;

import java.io.File;
import java.io.IOException;
import java.time.Duration;
import java.util.Collections;

import org.junit.Test;
import org.mockito.MockedStatic;

import ctbrec.Config;
import ctbrec.Recording;
import ctbrec.recorder.RecordingManager;
import ctbrec.recorder.download.Download;
import ctbrec.recorder.download.VideoLengthDetector;

public class DeleteTooShortTest extends AbstractPpTest {

    @Test
    public void tooShortSingleFileRecShouldBeDeleted() throws IOException, InterruptedException {
        testProcess(original);
    }

    @Test
    public void tooShortDirectoryRecShouldBeDeleted() throws IOException, InterruptedException {
        testProcess(originalDir);
    }

    private void testProcess(File original) throws IOException {
        Recording rec = createRec(original);
        Config config = mockConfig();
        MockedStatic<VideoLengthDetector> videoLengthDetectorMock = mockStatic(VideoLengthDetector.class);
        when(VideoLengthDetector.getLength(any())).thenReturn(Duration.ofSeconds(5));
        RecordingManager recordingManager = new RecordingManager(config, Collections.emptyList());
        recordingManager.add(rec);

        assertEquals(1, recordingManager.getAll().size());

        DeleteTooShort pp = new DeleteTooShort();
        pp.getConfig().put(DeleteTooShort.MIN_LEN_IN_SECS, "10");
        pp.postprocess(rec, recordingManager, config);

        assertFalse(rec.getAbsoluteFile().exists());
        assertFalse(original.exists());
        assertEquals(0, recordingManager.getAll().size());

        videoLengthDetectorMock.close();
    }

    @Test
    public void testGetName() {
        assertEquals("delete too short", new DeleteTooShort().getName());
    }

    @Test
    public void testDisabledWithSingleFile() throws IOException, InterruptedException {
        Recording rec = createRec(original);
        Config config = mockConfig();
        RecordingManager recordingManager = new RecordingManager(config, Collections.emptyList());
        recordingManager.add(rec);
        assertEquals(1, recordingManager.getAll().size());

        DeleteTooShort pp = new DeleteTooShort();
        pp.getConfig().put(DeleteTooShort.MIN_LEN_IN_SECS, "0");
        pp.postprocess(rec, recordingManager, config);

        assertTrue(rec.getAbsoluteFile().exists());
        assertTrue(original.exists());
        assertEquals(1, recordingManager.getAll().size());
    }

    @Test
    public void longEnoughVideoShouldStay() throws IOException, InterruptedException {
        Recording rec = createRec(original);
        Config config = mockConfig();
        RecordingManager recordingManager = new RecordingManager(config, Collections.emptyList());
        recordingManager.add(rec);
        assertEquals(1, recordingManager.getAll().size());

        DeleteTooShort pp = new DeleteTooShort();
        pp.getConfig().put(DeleteTooShort.MIN_LEN_IN_SECS, "1");
        pp.postprocess(rec, recordingManager, config);

        assertTrue(rec.getAbsoluteFile().exists());
        assertTrue(original.exists());
        assertEquals(1, recordingManager.getAll().size());
    }

    private Recording createRec(File original) {
        Download download = mock(Download.class);
        Recording rec = new Recording();
        rec.setModel(mockModel());
        rec.setAbsoluteFile(original);
        rec.setPostProcessedFile(original);
        rec.setStartDate(now);
        rec.setSingleFile(true);
        rec.setDownload(download);
        return rec;
    }
}
