// Path: src/main/java/Schillsaver/job/archive/Archiver.java
// public abstract class Archiver {
//     /**
//      * Packs one or more files into an archive.
//      *
//      * @param fileName
//      *          The archive file name.
//      *
//      * @param files
//      *          The files.
//      *
//      * @return
//      *          The archive file.
//      *
//      * @throws IllegalArgumentException
//      *          If an I/O error occurs.
//      */
//     public abstract File archive(final @NonNull String fileName, final List<File> files) throws IOException;
// 
//     /**
//      * Pads the specified file to ensure it contains enough data to have an exact number of frames.
//      *
//      * If there are, for example, 1401 bytes and the frame size is 1400 bytes, then FFMPEG will display an
//      * error about not having a full frame worth of bytes.
//      *
//      * @param file
//      *          The file.
//      *
//      * @throws NullPointerException
//      *          If the file or settings is null.
//      */
//     protected File padFile(final @NonNull File file) {
//         final Settings settings = Settings.getInstance();
// 
//         try (final FileOutputStream outputStream = new FileOutputStream(file, true)) {
//             final FrameDimension frameDimension = FrameDimension.valueOf(settings.getStringSetting("Encoding Frame Dimensions"));
//             final int blockSize = BlockSize.valueOf(settings.getStringSetting("Encoding Block Size")).getBlockSize();
// 
//             int bytesPerFrame = frameDimension.getWidth() * frameDimension.getHeight();
//             bytesPerFrame /= blockSize * blockSize;
//             bytesPerFrame /= 8;
// 
//             final int numberOfBytesToPad = bytesPerFrame - (int) (file.length() % bytesPerFrame);
// 
//             outputStream.write(new byte[numberOfBytesToPad]);
//         } catch (final IOException e) {
// 			e.printStackTrace();
//         }
// 
//         return file;
//     }
// 
//     /**
//      * Retrieves the file name, appended with the archive extension.
//      *
//      * @return
//      *          The file name, appended with the archive extension.
//      */
//     public abstract String getFileName(final String fileName);
// }
// 
// Path: src/main/java/Schillsaver/job/archive/ArchiverFactory.java
// public class ArchiverFactory {
//     /** The cache of created archivers. */
//     private final static HashMap<ArchiveType, Archiver> CACHE = new HashMap<>();
// 
//     // Ensure no instance of the factory can be created.
//     private ArchiverFactory() {}
// 
//     /**
//      * Creates a new archiver.
//      *
//      * @param type
//      *          The type.
//      *
//      * @return
//      *          The archiver.
//      *
//      * @throws NullPointerException
//      *          If the type is null.
//      */
//     public static Archiver create(final @NonNull ArchiveType type) {
//         if (CACHE.containsKey(type)) {
//             return CACHE.get(type);
//         }
// 
//         switch (type) {
//             case ZIP: {
//                 final ZipArchiver archiver = new ZipArchiver();
//                 CACHE.put(type, archiver);
//                 return archiver;
//             }
//             default: {
//                 throw new UnsupportedOperationException("The '" + type.name() + "' archiver is not supported.");
//             }
//         }
//     }
// }


import Schillsaver.job.archive.Archiver;
import Schillsaver.job.archive.ArchiverFactory;
import lombok.Getter;
import lombok.NonNull;
import java.io.*;
import java.util.List;
package Schillsaver.job;



public class Job implements Serializable {
    private static final long serialVersionUID = 1;

    /** The name of the Job. */
    @Getter private final String name;
    /** The output directory. */
    @Getter private final String outputDirectory;
    /** The archiver used to archive the file(s). */
    @Getter private final Archiver archiver;
    /** The file(s) to process.*/
    @Getter private final List<File> files;
    /** Whether the Job is an Encode Job or a Decode Job. */
    @Getter private final boolean isEncodeJob;

    /**
     * Constructs a new Job.
     *
     * @param builder
     *          The builder
     *
     * @throws NullPointerException
     *          If the builder is null.
     */
    Job(final @NonNull JobBuilder builder) {
        name = builder.getName();
        outputDirectory = builder.getOutputDirectory();
// Path: src/main/java/Schillsaver/job/archive/Archiver.java
// public abstract class Archiver {
//     /**
//      * Packs one or more files into an archive.
//      *
//      * @param fileName
//      *          The archive file name.
//      *
//      * @param files
//      *          The files.
//      *
//      * @return
//      *          The archive file.
//      *
//      * @throws IllegalArgumentException
//      *          If an I/O error occurs.
//      */
//     public abstract File archive(final @NonNull String fileName, final List<File> files) throws IOException;
// 
//     /**
//      * Pads the specified file to ensure it contains enough data to have an exact number of frames.
//      *
//      * If there are, for example, 1401 bytes and the frame size is 1400 bytes, then FFMPEG will display an
//      * error about not having a full frame worth of bytes.
//      *
//      * @param file
//      *          The file.
//      *
//      * @throws NullPointerException
//      *          If the file or settings is null.
//      */
//     protected File padFile(final @NonNull File file) {
//         final Settings settings = Settings.getInstance();
// 
//         try (final FileOutputStream outputStream = new FileOutputStream(file, true)) {
//             final FrameDimension frameDimension = FrameDimension.valueOf(settings.getStringSetting("Encoding Frame Dimensions"));
//             final int blockSize = BlockSize.valueOf(settings.getStringSetting("Encoding Block Size")).getBlockSize();
// 
//             int bytesPerFrame = frameDimension.getWidth() * frameDimension.getHeight();
//             bytesPerFrame /= blockSize * blockSize;
//             bytesPerFrame /= 8;
// 
//             final int numberOfBytesToPad = bytesPerFrame - (int) (file.length() % bytesPerFrame);
// 
//             outputStream.write(new byte[numberOfBytesToPad]);
//         } catch (final IOException e) {
// 			e.printStackTrace();
//         }
// 
//         return file;
//     }
// 
//     /**
//      * Retrieves the file name, appended with the archive extension.
//      *
//      * @return
//      *          The file name, appended with the archive extension.
//      */
//     public abstract String getFileName(final String fileName);
// }
// 
// Path: src/main/java/Schillsaver/job/archive/ArchiverFactory.java
// public class ArchiverFactory {
//     /** The cache of created archivers. */
//     private final static HashMap<ArchiveType, Archiver> CACHE = new HashMap<>();
// 
//     // Ensure no instance of the factory can be created.
//     private ArchiverFactory() {}
// 
//     /**
//      * Creates a new archiver.
//      *
//      * @param type
//      *          The type.
//      *
//      * @return
//      *          The archiver.
//      *
//      * @throws NullPointerException
//      *          If the type is null.
//      */
//     public static Archiver create(final @NonNull ArchiveType type) {
//         if (CACHE.containsKey(type)) {
//             return CACHE.get(type);
//         }
// 
//         switch (type) {
//             case ZIP: {
//                 final ZipArchiver archiver = new ZipArchiver();
//                 CACHE.put(type, archiver);
//                 return archiver;
//             }
//             default: {
//                 throw new UnsupportedOperationException("The '" + type.name() + "' archiver is not supported.");
//             }
//         }
//     }
// }


// Path: src/main/java/Schillsaver/job/Job.java
import Schillsaver.job.archive.Archiver;
import Schillsaver.job.archive.ArchiverFactory;
import lombok.Getter;
import lombok.NonNull;
import java.io.*;
import java.util.List;

package Schillsaver.job;



public class Job implements Serializable {
    private static final long serialVersionUID = 1;

    /** The name of the Job. */
    @Getter private final String name;
    /** The output directory. */
    @Getter private final String outputDirectory;
    /** The archiver used to archive the file(s). */
    @Getter private final Archiver archiver;
    /** The file(s) to process.*/
    @Getter private final List<File> files;
    /** Whether the Job is an Encode Job or a Decode Job. */
    @Getter private final boolean isEncodeJob;

    /**
     * Constructs a new Job.
     *
     * @param builder
     *          The builder
     *
     * @throws NullPointerException
     *          If the builder is null.
     */
    Job(final @NonNull JobBuilder builder) {
        name = builder.getName();
        outputDirectory = builder.getOutputDirectory();
        archiver = ArchiverFactory.create(builder.getArchiveType());