// Path: src/main/java/eu/goodlike/hls/download/ffmpeg/FfmpegProcessor.java
// public interface FfmpegProcessor {
// 
//     /**
//      * Spawns an ffmpeg process with given input, output and any additional params provided by the implementation
//      *
//      * @param output output file name
//      * @param firstInput input file name
//      * @param inputs additional input file names
//      * @return future which completes when the process finishes
//      * @throws NullPointerException if output, firstInput or inputs is or contains null
//      */
//     CompletableFuture<?> processFfmpeg(String output, String firstInput, String... inputs);
// 
// }


import com.google.common.base.MoreObjects;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import eu.goodlike.functional.Futures;
import eu.goodlike.hls.download.ffmpeg.FfmpegProcessor;
import eu.goodlike.neat.Null;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
package eu.goodlike.hls.download.m3u.data;



/**
 * Media playlist data which has separate video and audio streams; these streams are combined when processing
 */
public final class MultiMediaPlaylistData implements PlaylistData {

    @Override
    public CompletableFuture<?> handlePlaylistData() {
        return Futures.allOf(videoData.writePlaylistToFile(), audioData.writePlaylistToFile())
                .thenCompose(this::processPlaylist);
    }

    // CONSTRUCTORS

    @Inject
    public MultiMediaPlaylistData(@Assisted("video") MediaPlaylistData videoData,
                                  @Assisted("audio") MediaPlaylistData audioData,
                                  FfmpegProcessor ffmpegProcessor) {
        Null.check(videoData, audioData).as("videoData, audioData");

        this.videoData = videoData;
        this.audioData = audioData;

        this.ffmpegProcessor = ffmpegProcessor;
    }

    // PRIVATE

    private final MediaPlaylistData videoData;
    private final MediaPlaylistData audioData;

    private final FfmpegProcessor ffmpegProcessor;

    private CompletableFuture<?> processPlaylist(List<String> filenames) {
        String videoFilename = filenames.get(0);
        String audioFilename = filenames.get(1);
        return ffmpegProcessor.processFfmpeg(videoFilename, videoFilename, audioFilename);
    }

    // OBJECT OVERRIDES

    @Override
    public String toString() {
// Path: src/main/java/eu/goodlike/hls/download/ffmpeg/FfmpegProcessor.java
// public interface FfmpegProcessor {
// 
//     /**
//      * Spawns an ffmpeg process with given input, output and any additional params provided by the implementation
//      *
//      * @param output output file name
//      * @param firstInput input file name
//      * @param inputs additional input file names
//      * @return future which completes when the process finishes
//      * @throws NullPointerException if output, firstInput or inputs is or contains null
//      */
//     CompletableFuture<?> processFfmpeg(String output, String firstInput, String... inputs);
// 
// }


// Path: src/main/java/eu/goodlike/hls/download/m3u/data/MultiMediaPlaylistData.java
import com.google.common.base.MoreObjects;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import eu.goodlike.functional.Futures;
import eu.goodlike.hls.download.ffmpeg.FfmpegProcessor;
import eu.goodlike.neat.Null;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;

package eu.goodlike.hls.download.m3u.data;



/**
 * Media playlist data which has separate video and audio streams; these streams are combined when processing
 */
public final class MultiMediaPlaylistData implements PlaylistData {

    @Override
    public CompletableFuture<?> handlePlaylistData() {
        return Futures.allOf(videoData.writePlaylistToFile(), audioData.writePlaylistToFile())
                .thenCompose(this::processPlaylist);
    }

    // CONSTRUCTORS

    @Inject
    public MultiMediaPlaylistData(@Assisted("video") MediaPlaylistData videoData,
                                  @Assisted("audio") MediaPlaylistData audioData,
                                  FfmpegProcessor ffmpegProcessor) {
        Null.check(videoData, audioData).as("videoData, audioData");

        this.videoData = videoData;
        this.audioData = audioData;

        this.ffmpegProcessor = ffmpegProcessor;
    }

    // PRIVATE

    private final MediaPlaylistData videoData;
    private final MediaPlaylistData audioData;

    private final FfmpegProcessor ffmpegProcessor;

    private CompletableFuture<?> processPlaylist(List<String> filenames) {
        String videoFilename = filenames.get(0);
        String audioFilename = filenames.get(1);
        return ffmpegProcessor.processFfmpeg(videoFilename, videoFilename, audioFilename);
    }

    // OBJECT OVERRIDES

    @Override
    public String toString() {
        return MoreObjects.toStringHelper("MultiMediaPlaylistData")