// Path: ooso/src/main/java/fr/d2si/ooso/launcher/Launcher.java
// public class Launcher {
//     private JobInfo jobInfo;
// 
//     private MapperAbstract mapper;
//     private ReducerAbstract reducer;
// 
//     private boolean generateId = false;
// 
//     private Logger logger;
// 
//     public Launcher withMapper(MapperAbstract mapper) {
//         this.mapper = mapper;
//         return this;
//     }
// 
//     public Launcher withReducer(ReducerAbstract reducer) {
//         this.reducer = reducer;
//         return this;
//     }
// 
//     public Launcher withRandomId(boolean generateId) {
//         this.generateId = generateId;
//         return this;
//     }
// 
//     public String launchJob() {
//         try {
//             String generatedId = null;
// 
//             configureLogger();
//             loadJobInfo();
// 
//             if (generateId) {
//                 generatedId = generateUUID().toString();
//                 jobInfo.setJobId(generatedId);
//             }
// 
//             if (this.mapper == null || (!this.jobInfo.getDisableReducer() && reducer == null)) {
//                 throw new RuntimeException("You must set the mapper and reducer classes");
//             }
// 
//             launchMappersDriver();
// 
//             return generatedId;
//         } catch (IOException e) {
//             throw new RuntimeException(e);
//         }
//     }
// 
//     private UUID generateUUID() {
//         return new UUID();
//     }
// 
//     private void configureLogger() {
//         this.logger = Logger.getAnonymousLogger();
//     }
// 
//     private void loadJobInfo() throws IOException {
//         this.logger.info("Loading Job Configuration...");
// 
//         Gson gson = new Gson();
//         InputStream driverInfoStream = getClass().getClassLoader().getResourceAsStream("jobInfo.json");
//         BufferedReader driverInfoReader = new BufferedReader(new InputStreamReader(driverInfoStream));
//         this.jobInfo = gson.fromJson(driverInfoReader, JobInfo.class);
//         driverInfoReader.close();
//     }
// 
//     private void launchMappersDriver() throws IOException {
//         this.logger.info("Serializing mapper and reducer...");
// 
//         String mapperInBase64 = Commons.objectToBase64(this.mapper);
//         String reducerInBase64 = Commons.objectToBase64(this.reducer);
// 
//         this.logger.info("Launching job...");
// 
//         MappersDriverInfo mappersDriverInfo = new MappersDriverInfo(mapperInBase64, reducerInBase64, this.jobInfo);
// 
//         Commons.invokeLambdaAsync(this.jobInfo.getMappersDriverFunctionName(), mappersDriverInfo);
//     }
// }
// 
// Path: examples/ad-hoc-example-1/src/main/java/mapper/Mapper.java
// public class Mapper extends MapperAbstract {
// 
//     public String map(BufferedReader objectBufferedReader) {
// 
//         try {
//             Map<String, Long> transactionsPerProduct = new HashMap<>();
// 
//             String line;
//             while (((line = objectBufferedReader.readLine()) != null)) {
//                 String[] fields = line.split(",");
//                 String productId = fields[3];
//                 Long currentCount = transactionsPerProduct.get(productId);
//                 transactionsPerProduct.put(productId, currentCount != null ? currentCount + 1 : 1);
//             }
// 
//             Gson gson = new Gson();
//             return gson.toJson(transactionsPerProduct);
//         } catch (IOException e) {
//             e.printStackTrace();
//         }
//         return null;
//     }
// }
// 
// Path: examples/ad-hoc-example-1/src/main/java/reducer/Reducer.java
// public class Reducer extends ReducerAbstract {
// 
//     public String reduce(List<ObjectInfoSimple> batch) {
//         try {
//             Gson gson = new Gson();
// 
//             Map<String, Double> reduceTransactionCountPerProduct = new HashMap<>();
// 
//             for (ObjectInfoSimple objectInfo : batch) {
// 
//                 BufferedReader objectBufferedReader = Commons.getReaderFromObjectInfo(objectInfo);
// 
//                 Map<String, Double> transactionCountPerProduct = gson.fromJson(objectBufferedReader, HashMap.class);
//                 transactionCountPerProduct.forEach((k, v) -> reduceTransactionCountPerProduct.merge(k, v, (v1, v2) -> v1 + v2));
// 
//                 objectBufferedReader.close();
//             }
// 
//             return gson.toJson(reduceTransactionCountPerProduct);
//         } catch (IOException e) {
//             e.printStackTrace();
//         }
//         return null;
//     }
// }


import com.amazonaws.services.s3.AmazonS3;
import fr.d2si.ooso.launcher.Launcher;
import fr.d2si.ooso.utils.*;
import mapper.Mapper;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import reducer.Reducer;
import java.io.File;
        s3Client.createBucket(Commons.getBucketFromFullPath(jobInfo.getJobInputBucket()));
        s3Client.createBucket(jobInfo.getMapperOutputBucket());
        s3Client.createBucket(jobInfo.getReducerOutputBucket());

        //putting test data in local s3 bucket
        File dataDir = new File(new File("").getAbsoluteFile() + "/test-data/250mb");
        for (File file : dataDir.listFiles()) {
            Commons.storeObject(Commons.TEXT_TYPE, file, Commons.getBucketFromFullPath(jobInfo.getJobInputBucket()), "250mb/" + file.getName());
        }

    }

    @AfterClass
    public static void tearDown() throws Exception {
        File dataDir = new File(new File("").getAbsoluteFile() + "/test-data/250mb");
        for (File file : dataDir.listFiles())
            s3Client.deleteObject(Commons.getBucketFromFullPath(jobInfo.getJobInputBucket()), "250mb/" + file.getName());

        Commons.emptyBucket(Commons.getBucketFromFullPath(jobInfo.getJobInputBucket()));
        Commons.emptyBucket(jobInfo.getMapperOutputBucket());
        Commons.emptyBucket(jobInfo.getReducerOutputBucket());

        s3Client.deleteBucket(Commons.getBucketFromFullPath(jobInfo.getJobInputBucket()));
        s3Client.deleteBucket(jobInfo.getMapperOutputBucket());
        s3Client.deleteBucket(jobInfo.getReducerOutputBucket());

    }

    @Test
    public void normalExec() throws Exception {
// Path: ooso/src/main/java/fr/d2si/ooso/launcher/Launcher.java
// public class Launcher {
//     private JobInfo jobInfo;
// 
//     private MapperAbstract mapper;
//     private ReducerAbstract reducer;
// 
//     private boolean generateId = false;
// 
//     private Logger logger;
// 
//     public Launcher withMapper(MapperAbstract mapper) {
//         this.mapper = mapper;
//         return this;
//     }
// 
//     public Launcher withReducer(ReducerAbstract reducer) {
//         this.reducer = reducer;
//         return this;
//     }
// 
//     public Launcher withRandomId(boolean generateId) {
//         this.generateId = generateId;
//         return this;
//     }
// 
//     public String launchJob() {
//         try {
//             String generatedId = null;
// 
//             configureLogger();
//             loadJobInfo();
// 
//             if (generateId) {
//                 generatedId = generateUUID().toString();
//                 jobInfo.setJobId(generatedId);
//             }
// 
//             if (this.mapper == null || (!this.jobInfo.getDisableReducer() && reducer == null)) {
//                 throw new RuntimeException("You must set the mapper and reducer classes");
//             }
// 
//             launchMappersDriver();
// 
//             return generatedId;
//         } catch (IOException e) {
//             throw new RuntimeException(e);
//         }
//     }
// 
//     private UUID generateUUID() {
//         return new UUID();
//     }
// 
//     private void configureLogger() {
//         this.logger = Logger.getAnonymousLogger();
//     }
// 
//     private void loadJobInfo() throws IOException {
//         this.logger.info("Loading Job Configuration...");
// 
//         Gson gson = new Gson();
//         InputStream driverInfoStream = getClass().getClassLoader().getResourceAsStream("jobInfo.json");
//         BufferedReader driverInfoReader = new BufferedReader(new InputStreamReader(driverInfoStream));
//         this.jobInfo = gson.fromJson(driverInfoReader, JobInfo.class);
//         driverInfoReader.close();
//     }
// 
//     private void launchMappersDriver() throws IOException {
//         this.logger.info("Serializing mapper and reducer...");
// 
//         String mapperInBase64 = Commons.objectToBase64(this.mapper);
//         String reducerInBase64 = Commons.objectToBase64(this.reducer);
// 
//         this.logger.info("Launching job...");
// 
//         MappersDriverInfo mappersDriverInfo = new MappersDriverInfo(mapperInBase64, reducerInBase64, this.jobInfo);
// 
//         Commons.invokeLambdaAsync(this.jobInfo.getMappersDriverFunctionName(), mappersDriverInfo);
//     }
// }
// 
// Path: examples/ad-hoc-example-1/src/main/java/mapper/Mapper.java
// public class Mapper extends MapperAbstract {
// 
//     public String map(BufferedReader objectBufferedReader) {
// 
//         try {
//             Map<String, Long> transactionsPerProduct = new HashMap<>();
// 
//             String line;
//             while (((line = objectBufferedReader.readLine()) != null)) {
//                 String[] fields = line.split(",");
//                 String productId = fields[3];
//                 Long currentCount = transactionsPerProduct.get(productId);
//                 transactionsPerProduct.put(productId, currentCount != null ? currentCount + 1 : 1);
//             }
// 
//             Gson gson = new Gson();
//             return gson.toJson(transactionsPerProduct);
//         } catch (IOException e) {
//             e.printStackTrace();
//         }
//         return null;
//     }
// }
// 
// Path: examples/ad-hoc-example-1/src/main/java/reducer/Reducer.java
// public class Reducer extends ReducerAbstract {
// 
//     public String reduce(List<ObjectInfoSimple> batch) {
//         try {
//             Gson gson = new Gson();
// 
//             Map<String, Double> reduceTransactionCountPerProduct = new HashMap<>();
// 
//             for (ObjectInfoSimple objectInfo : batch) {
// 
//                 BufferedReader objectBufferedReader = Commons.getReaderFromObjectInfo(objectInfo);
// 
//                 Map<String, Double> transactionCountPerProduct = gson.fromJson(objectBufferedReader, HashMap.class);
//                 transactionCountPerProduct.forEach((k, v) -> reduceTransactionCountPerProduct.merge(k, v, (v1, v2) -> v1 + v2));
// 
//                 objectBufferedReader.close();
//             }
// 
//             return gson.toJson(reduceTransactionCountPerProduct);
//         } catch (IOException e) {
//             e.printStackTrace();
//         }
//         return null;
//     }
// }


// Path: examples/ad-hoc-example-1/src/test/java/integration_test/NormalExecutionTest.java
import com.amazonaws.services.s3.AmazonS3;
import fr.d2si.ooso.launcher.Launcher;
import fr.d2si.ooso.utils.*;
import mapper.Mapper;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import reducer.Reducer;
import java.io.File;

        s3Client.createBucket(Commons.getBucketFromFullPath(jobInfo.getJobInputBucket()));
        s3Client.createBucket(jobInfo.getMapperOutputBucket());
        s3Client.createBucket(jobInfo.getReducerOutputBucket());

        //putting test data in local s3 bucket
        File dataDir = new File(new File("").getAbsoluteFile() + "/test-data/250mb");
        for (File file : dataDir.listFiles()) {
            Commons.storeObject(Commons.TEXT_TYPE, file, Commons.getBucketFromFullPath(jobInfo.getJobInputBucket()), "250mb/" + file.getName());
        }

    }

    @AfterClass
    public static void tearDown() throws Exception {
        File dataDir = new File(new File("").getAbsoluteFile() + "/test-data/250mb");
        for (File file : dataDir.listFiles())
            s3Client.deleteObject(Commons.getBucketFromFullPath(jobInfo.getJobInputBucket()), "250mb/" + file.getName());

        Commons.emptyBucket(Commons.getBucketFromFullPath(jobInfo.getJobInputBucket()));
        Commons.emptyBucket(jobInfo.getMapperOutputBucket());
        Commons.emptyBucket(jobInfo.getReducerOutputBucket());

        s3Client.deleteBucket(Commons.getBucketFromFullPath(jobInfo.getJobInputBucket()));
        s3Client.deleteBucket(jobInfo.getMapperOutputBucket());
        s3Client.deleteBucket(jobInfo.getReducerOutputBucket());

    }

    @Test
    public void normalExec() throws Exception {
        new Launcher()