package ctbrec.recorder.postprocessing;

import static java.nio.charset.StandardCharsets.*;
import static java.nio.file.StandardOpenOption.*;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Instant;

import org.apache.commons.io.FileUtils;
import org.junit.After;
import org.junit.Before;
import org.mockito.MockedStatic;

import ctbrec.Config;
import ctbrec.Model;
import ctbrec.Settings;
import ctbrec.recorder.RecordingManager;
import ctbrec.sites.Site;
import ctbrec.sites.chaturbate.Chaturbate;

public abstract class AbstractPpTest {
    Path baseDir;
    Path recDir;
    File original;
    File postProcessed;
    File originalDir;
    File postProcessedDir;
    Instant now = Instant.now();
    RecordingManager recordingManager;

    MockedStatic<Config> configStatic;

    @Before
    public void setup() throws IOException {
        baseDir = Files.createTempDirectory("ctbrec_test_");
        recDir = baseDir.resolve("recordings");
        original = new File(recDir.toFile(), "original.ts");
        postProcessed = new File(recDir.toFile(), "postProcessed.ts");
        originalDir = new File(recDir.toFile(), "original");
        postProcessedDir = new File(recDir.toFile(), "postProcessed");
        Files.createDirectories(original.getParentFile().toPath());
        Files.write(original.toPath(), "foobar".getBytes(UTF_8), CREATE_NEW, WRITE, TRUNCATE_EXISTING);
        Files.write(postProcessed.toPath(), "foobar".getBytes(UTF_8), CREATE_NEW, WRITE, TRUNCATE_EXISTING);
        Files.createDirectories(originalDir.toPath());
        FileUtils.touch(new File(originalDir, "playlist.m3u8"));
    }

    @After
    public void teardown() throws IOException {
        FileUtils.deleteDirectory(baseDir.toFile());
        if (configStatic != null) {
            configStatic.close();
            configStatic = null;
        }
    }

    Config mockConfig() {
        Config config = mock(Config.class);
        when(config.getSettings()).thenReturn(mockSettings());
        when(config.getModelNotes(any())).thenReturn("tag, foo, bar");
        when(config.getConfigDir()).thenReturn(new File(baseDir.toFile(), "config"));
        configStatic = mockStatic(Config.class);
        configStatic.when(Config::getInstance).thenReturn(config);
        return config;
    }

    Model mockModel() {
        Site site = new Chaturbate();
        Model model = site.createModel("Mockita Boobilicious");
        model.setDisplayName("Mockita Boobilicious");
        return model;
    }

    Settings mockSettings() {
        Settings settings = new Settings();
        settings.recordingsDir = recDir.toString();
        return settings;
    }
}
