package ctbrec.recorder.postprocessing;

import static org.junit.Assert.*;

import java.io.IOException;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

import org.junit.Before;
import org.junit.Test;

import ctbrec.Config;
import ctbrec.Recording;

public class AbstractPlaceholderAwarePostProcessorTest extends AbstractPpTest {

    Recording rec;
    Config config;
    Move placeHolderAwarePp;

    @Override
    @Before
    public void setup() throws IOException {
        super.setup();
        rec = new Recording();
        rec.setModel(mockModel());
        rec.setAbsoluteFile(original);
        rec.setPostProcessedFile(postProcessed);
        rec.setStartDate(now);
        rec.setSingleFile(true);
        config = mockConfig();
        placeHolderAwarePp = new Move();
    }

    @Test
    public void testModelNameReplacement() {
        String input = "asdf_${modelName}_asdf";
        assertEquals("asdf_Mockita Boobilicious_asdf", placeHolderAwarePp.fillInPlaceHolders(input, rec, config));
        input = "asdf_${modelDisplayName}_asdf";
        assertEquals("asdf_Mockita Boobilicious_asdf", placeHolderAwarePp.fillInPlaceHolders(input, rec, config));
        input = "asdf_${modelSanitizedName}_asdf";
        assertEquals("asdf_Mockita_Boobilicious_asdf", placeHolderAwarePp.fillInPlaceHolders(input, rec, config));
    }

    @Test
    public void testSiteNameReplacement() {
        String input = "asdf_${siteName}_asdf";
        assertEquals("asdf_Chaturbate_asdf", placeHolderAwarePp.fillInPlaceHolders(input, rec, config));
        input = "asdf_${siteSanitizedName}_asdf";
        assertEquals("asdf_Chaturbate_asdf", placeHolderAwarePp.fillInPlaceHolders(input, rec, config));
    }

    @Test
    public void testUtcTimeReplacement() {
        // without user defined pattern
        String date = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH-mm-ss")
                .withLocale(Locale.US)
                .withZone(ZoneOffset.UTC)
                .format(rec.getStartDate());
        String input = "asdf_${utcDateTime}_asdf";
        assertEquals("asdf_" + date + "_asdf", placeHolderAwarePp.fillInPlaceHolders(input, rec, config));

        // with user defined pattern
        date = DateTimeFormatter.ofPattern("yyyyMMdd-HHmmss")
                .withLocale(Locale.US)
                .withZone(ZoneOffset.UTC)
                .format(rec.getStartDate());
        input = "asdf_${utcDateTime(yyyyMMdd-HHmmss)}_asdf";
        assertEquals("asdf_" + date + "_asdf", placeHolderAwarePp.fillInPlaceHolders(input, rec, config));

        // multiple occurences with user defined patterns
        date = DateTimeFormatter.ofPattern("yyyy-MM-dd/yyyy")
                .withLocale(Locale.US)
                .withZone(ZoneOffset.UTC)
                .format(rec.getStartDate());
        input = "asdf_${utcDateTime(yyyy)}-${utcDateTime(MM)}-${utcDateTime(dd)}/${utcDateTime(yyyy)}_asdf";
        assertEquals("asdf_" + date + "_asdf", placeHolderAwarePp.fillInPlaceHolders(input, rec, config));
    }

    @Test
    public void testLocalTimeReplacement() {
        String date = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH-mm-ss")
                .withLocale(Locale.US)
                .withZone(ZoneId.systemDefault())
                .format(rec.getStartDate());
        String input = "asdf_${localDateTime}_asdf";
        assertEquals("asdf_" + date + "_asdf", placeHolderAwarePp.fillInPlaceHolders(input, rec, config));

        date = DateTimeFormatter.ofPattern("yyyyMMdd-HHmmss")
                .withLocale(Locale.US)
                .withZone(ZoneId.systemDefault())
                .format(rec.getStartDate());
        input = "asdf_${localDateTime(yyyyMMdd-HHmmss)}_asdf";
        assertEquals("asdf_" + date + "_asdf", placeHolderAwarePp.fillInPlaceHolders(input, rec, config));
    }

    @Test
    public void testEpochReplacement() {
        long epoch = now.toEpochMilli() / 1000;
        String input = "asdf_${epochSecond}_asdf";
        assertEquals("asdf_" + epoch + "_asdf", placeHolderAwarePp.fillInPlaceHolders(input, rec, config));
    }

    @Test
    public void testFileSuffixReplacement() {
        String input = "asdf_${fileSuffix}_asdf";
        assertEquals("asdf_ts_asdf", placeHolderAwarePp.fillInPlaceHolders(input, rec, config));
    }

    @Test
    public void testRecordingsDirReplacement() {
        String input = "asdf_${recordingsDir}_asdf";
        assertEquals("asdf_" + recDir.toString() + "_asdf", placeHolderAwarePp.fillInPlaceHolders(input, rec, config));
    }

    @Test
    public void testAbsolutePathReplacement() {
        String input = "asdf_${absolutePath}_asdf";
        assertEquals("asdf_" + postProcessed.getAbsolutePath().toString() + "_asdf", placeHolderAwarePp.fillInPlaceHolders(input, rec, config));
    }

    @Test
    public void testAbsoluteParentPathReplacement() {
        String input = "asdf_${absoluteParentPath}_asdf";
        assertEquals("asdf_" + postProcessed.getParentFile().toString() + "_asdf", placeHolderAwarePp.fillInPlaceHolders(input, rec, config));
    }

    @Test
    public void testModelNotesReplacement() {
        String input = "asdf_${modelNotes}_asdf";
        assertEquals("asdf_tag,_foo,_bar_asdf", placeHolderAwarePp.fillInPlaceHolders(input, rec, config));
    }
}
