package ctbrec.recorder.postprocessing;

import java.io.File;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.Arrays;
import java.util.Locale;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ctbrec.Config;
import ctbrec.OS;
import ctbrec.Recording;
import ctbrec.recorder.FFmpeg;
import ctbrec.recorder.RecordingManager;

public class CreateContactSheet extends AbstractPlaceholderAwarePostProcessor {

    private static final Logger LOG = LoggerFactory.getLogger(CreateContactSheet.class);

    public static final String TOTAL_SIZE = "total_size";
    public static final String PADDING = "padding";
    public static final String COLS = "columns";
    public static final String ROWS = "rows";
    public static final String BACKGROUND = "background";
    public static final String FILENAME = "filename";


    @Override
    public String getName() {
        return "create contact sheet";
    }

    @Override
    public boolean postprocess(Recording rec, RecordingManager recordingManager, Config config) throws IOException, InterruptedException {
        int totalWidth = Integer.parseInt(getConfig().getOrDefault(TOTAL_SIZE, "1920"));
        int padding = Integer.parseInt(getConfig().getOrDefault(PADDING, "4"));
        int cols = Integer.parseInt(getConfig().getOrDefault(COLS, "8"));
        int rows = Integer.parseInt(getConfig().getOrDefault(ROWS, "7"));
        String color = getConfig().getOrDefault(BACKGROUND, "0x333333");
        String filename = getConfig().getOrDefault(FILENAME, "contactsheet.jpg");

        int thumbWidth = (int) ((totalWidth - (cols + 1) * padding) / (double)cols);
        int numberOfThumbs = rows * cols;
        long lengthInSeconds = rec.getLength().getSeconds();
        double thumbnailInterval = lengthInSeconds / (double)numberOfThumbs;

        MessageFormat mf = new MessageFormat("fps=1/{0},scale={4}:-1,tile={1}x{2}:color={6}:margin={3}:padding={3},scale={5}:-1", Locale.ENGLISH);
        String filterArg = mf.format(new Object[] {
                thumbnailInterval,
                cols, rows,
                padding,
                Integer.toString(thumbWidth),
                Integer.toString(totalWidth),
                color},
                new StringBuffer(), null).toString();
        File executionDir = rec.getPostProcessedFile().isDirectory() ? rec.getPostProcessedFile() : rec.getPostProcessedFile().getParentFile();
        File output = new File(executionDir, fillInPlaceHolders(filename, rec, config));

        File input = getInputFile(rec);
        String[] args = {
                "-skip_frame",
                "nokey",
                "-i",
                input.getCanonicalPath(),
                "-vf",
                filterArg,
                "-an",
                "-vsync",
                "0",
                "-qscale:v",
                "3",
                "-y",
                "-frames:v",
                "1",
                output.getCanonicalPath()
        };
        String[] cmdline = OS.getFFmpegCommand(args);
        LOG.info("Executing {} in working directory {}", Arrays.toString(cmdline), executionDir);
        File ffmpegLog = new File(System.getProperty("java.io.tmpdir"), "create_contact_sheet_" + rec.getId() + ".log");
        FFmpeg ffmpeg = new FFmpeg.Builder()
                .logOutput(config.getSettings().logFFmpegOutput)
                .logFile(ffmpegLog)
                .build();
        ffmpeg.exec(cmdline, OS.getEnvironment(), executionDir);
        int exitCode = ffmpeg.waitFor();
        rec.getAssociatedFiles().add(output.getCanonicalPath());
        return exitCode != 1;
    }

    private File getInputFile(Recording rec) {
        if (rec.isSingleFile()) {
            return rec.getPostProcessedFile();
        } else {
            // TODO this has to be changed to support other playlist types like DASH
            return new File(rec.getPostProcessedFile(), "playlist.m3u8");
        }
    }
}
