package uk.ac.ebi.spot.goci.service;

import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import uk.ac.ebi.spot.goci.model.Association;
import uk.ac.ebi.spot.goci.model.AssociationUploadRow;
import uk.ac.ebi.spot.goci.model.AssociationValidationError;

import java.io.File;
import java.io.IOException;
import java.util.Collection;

/**
 * Created by emma on 01/04/2016.
 *
 * @author emma
 *         <p>
 *         This service class acts an an entry point for processing an XLSX file that contains GWAS association data
 */
@Service
public class AssociationFileUploadService {

    private SheetProcessor sheetProcessor;

    private AssociationRowProcessor associationRowProcessor;

    private AssociationValidationService associationValidationService;

    private Logger log = LoggerFactory.getLogger(getClass());

    protected Logger getLog() {
        return log;
    }

    @Autowired
    public AssociationFileUploadService(SheetProcessor sheetProcessor,
                                        AssociationRowProcessor associationRowProcessor,
                                        AssociationValidationService associationValidationService) {
        this.sheetProcessor = sheetProcessor;
        this.associationRowProcessor = associationRowProcessor;
        this.associationValidationService = associationValidationService;
    }

    /**
     * Process uploaded file
     *
     * @param file XLSX file supplied by user
     */
    public void processAssociationFile(File file) {

        if (!file.exists()) {
            // Create sheet
            XSSFSheet sheet = null;
            try {
                // Create a sheet for reading
                sheet = createSheet(file.getAbsolutePath());

                // Process file
                Collection<AssociationUploadRow> fileRows = sheetProcessor.readSheetRows(sheet);

                // Error check each row
                // Create a map of row and resulting association
                for (AssociationUploadRow row : fileRows) {

                    Integer rowNumber = row.getRowNumber();
                    String effectType = row.getEffectType();
                    Association association = associationRowProcessor.createAssociationFromUploadRow(row);

                    // TODO - should check level be supplied by user?
                    // TODO - will author spreadsheet have an effect type?
                    Collection<AssociationValidationError> errors =
                            associationValidationService.runAssociationValidation(association, "full", effectType);

                    // TODO - We need to collate all errors and present in log
                }
            }
            catch (InvalidFormatException | IOException e) {
                getLog().error("File: " + file.getName() + " cannot be processed", e);
            }
        }
        else {
            getLog().error("File: " + file.getName() + " cannot be found");
        }
    }

    /**
     * Create sheet from file, this is then used to read through each row
     *
     * @param fileName Name of XLSX file supplied by user
     */
    private XSSFSheet createSheet(String fileName) throws InvalidFormatException, IOException {

        // Open file
        OPCPackage pkg = OPCPackage.open(fileName);
        XSSFWorkbook current = new XSSFWorkbook(pkg);
        pkg.close(); // TODO WILL THIS CAUSE ISSUES?
        return current.getSheetAt(0);
    }
}
@@ -124,131 +124,32 @@
 poi.
-openxml4j.opc.OPCPackage;%0Aimport org.apache.poi.xssf.usermodel.XSSFSheet;%0Aimport org.apache.poi.xssf.usermodel.XSSFWorkbook
+xssf.usermodel.XSSFSheet
 ;%0Aim
@@ -814,16 +814,22 @@
 private 
+Upload
 SheetPro
@@ -827,33 +827,39 @@
 dSheetProcessor 
-s
+uploadS
 heetProcessor;%0A%0A
@@ -992,16 +992,72 @@
 rvice;%0A%0A
+    private SheetCreationService sheetCreationService;%0A%0A
     priv
@@ -1225,16 +1225,22 @@
 Service(
+Upload
 SheetPro
@@ -1246,17 +1246,23 @@
 ocessor 
-s
+uploadS
 heetProc
@@ -1454,16 +1454,99 @@
 nService
+,%0A                                        SheetCreationService sheetCreationService
 ) %7B%0A    
@@ -1554,17 +1554,23 @@
    this.
-s
+uploadS
 heetProc
@@ -1577,17 +1577,23 @@
 essor = 
-s
+uploadS
 heetProc
@@ -1737,16 +1737,74 @@
 ervice;%0A
+        this.sheetCreationService = sheetCreationService;%0A
     %7D%0A%0A 
@@ -2135,16 +2135,37 @@
 sheet = 
+sheetCreationService.
 createSh
@@ -2286,17 +2286,23 @@
 eRows = 
-s
+uploadS
 heetProc
@@ -3448,483 +3448,6 @@
    %7D
-%0A%0A    /**%0A     * Create sheet from file, this is then used to read through each row%0A     *%0A     * @param fileName Name of XLSX file supplied by user%0A     */%0A    private XSSFSheet createSheet(String fileName) throws InvalidFormatException, IOException %7B%0A%0A        // Open file%0A        OPCPackage pkg = OPCPackage.open(fileName);%0A        XSSFWorkbook current = new XSSFWorkbook(pkg);%0A        pkg.close(); // TODO WILL THIS CAUSE ISSUES?%0A        return current.getSheetAt(0);%0A    %7D
 %0A%7D

Add call to new interface