package uk.ac.ebi.quickgo.common.loader;

import uk.ac.ebi.quickgo.common.validator.DbXRefEntity;

import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static java.util.stream.Collectors.toList;

/**
 *
 * Read the file in the specified directory, and pass back the contents as a list.
 *
 *
 * @author Tony Wardell
 *         Date: 18/04/2016
 *         Time: 14:06
 *         Created with IntelliJ IDEA.
 *
 */
public class DbXRefLoader {

    private static final int COL_DATABASE = 0;
    private static final int COL_ENTITY_TYPE = 1;
    private static final int COL_ENTITY_TYPE_NAME = 2;
    private static final int COL_LOCAL_ID_SYNTAX = 3;
    private static final int COL_URL_SYNTAX = 4;
    private static final String COL_DELIMITER = "\t";
    private final Logger logger = LoggerFactory.getLogger(DbXRefLoader.class);
    private final String path;
    private final boolean caseSensitive;
    private static final boolean POSTGRES = true;
    protected boolean compress = true;

    public DbXRefLoader(String path, boolean caseSensitive) {

        this.path = path;
        this.caseSensitive = caseSensitive;
    }

    /**
     * Load the file which contains information about database cross references and save it to a list of
     * GeneProductDbXRefIDFormat instances.
     *
     * We load this file to use the regexes it contains to validate gene product ids (each Db will have it's own
     * regex for the id it uses).
     *
     * If the file cannot be loaded supply the client with an empty list, as we will continue without
     * validation, rather than end the process.
     *
     * Use directRead(fields[COL_LOCAL_ID_SYNTAX])?
     * @return a list of GeneProductDbXRefIDFormat instances that hold the validation regular expressions.
     */
    public List<DbXRefEntity> load() {

        try {

            Path path = FileSystems.getDefault().getPath(this.path);

            return GZIPFiles.lines(path)
                    .skip(1)    //header
                    .map(line -> line.split(COL_DELIMITER))
                    .map(fields -> new DbXRefEntity(fields[COL_DATABASE], fields[COL_ENTITY_TYPE],
                            fields[COL_ENTITY_TYPE_NAME], fields[COL_LOCAL_ID_SYNTAX], fields[COL_URL_SYNTAX],
                            caseSensitive))
                    .collect(toList());

        } catch (Exception e) {
            logger.error("DbXRefLoader failed to load file " + this.path + ", the source of validation regexes to " +
                    "validate gene product IDs. Gene Product ID validation will not take place", e);

            return Collections.emptyList();
        }

    }

    public String directRead(String input)  {
        StringBuilder field = new StringBuilder();
        List<String> data = new ArrayList<String>();
        String line;
        data.clear();
        boolean isNull = false;

        int count = 0;
//        line = rd.readLine();
        if (input == null) {
//            eof = true;
            return "";
        }

//        field.setLength(0);
        boolean escape = false;

        while (count < input.length()) {
            char ch = input.charAt(count);
            if (escape) {
                if (ch == 't') {
                    field.append('\t');
                }
                else if (ch == 'n') {
                    field.append('\n');
                }
                else if (ch == 'N') {
                    isNull = true;
                }
                else if (ch == '\\') {
                    field.append('\\');
                }
                escape = false;
            }
            // Not currently escaped
            else {
                if (ch == '\\' && POSTGRES) {
                    escape = true;
                }
                //Neither escaped nor postgres
                else {
                    if (ch == '\t') {
                        if (isNull) {
                            data.add(null);
                        }
                        else {
                            //data.add(field.toString());
                            return field.toString();
                        }
//                        field.setLength(0);
                        isNull = false;
                    }
                    else {
                        field.append(ch);
                    }
                }

            }
            count++;

//            if (count == line.length() && escape) {
//                line = rd.readLine();
//                if (line == null) {
//                    break;
//                }
//                count = 0;
//                escape = false;
//            }
        }

//        if (isNull){
//            data.add(null);
//        }
//        else {
//            data.add(field.toString());
//        }
        return field.toString();
    }


}

@@ -157,36 +157,8 @@
 th;%0A
-import java.util.ArrayList;%0A
 impo
@@ -183,16 +183,16 @@
 ctions;%0A
+
 import j
@@ -1024,97 +1024,8 @@
 ive;
-%0A    private static final boolean POSTGRES = true;%0A    protected boolean compress = true;
 %0A%0A  
@@ -1634,67 +1634,8 @@
 ss.%0A
-     *%0A     * Use directRead(fields%5BCOL_LOCAL_ID_SYNTAX%5D)?%0A
     
@@ -2618,2218 +2618,13 @@
  %7D%0A%0A
+
     %7D%0A%0A
-    public String directRead(String input)  %7B%0A        StringBuilder field = new StringBuilder();%0A        List%3CString%3E data = new ArrayList%3CString%3E();%0A        String line;%0A        data.clear();%0A        boolean isNull = false;%0A%0A        int count = 0;%0A//        line = rd.readLine();%0A        if (input == null) %7B%0A//            eof = true;%0A            return %22%22;%0A        %7D%0A%0A//        field.setLength(0);%0A        boolean escape = false;%0A%0A        while (count %3C input.length()) %7B%0A            char ch = input.charAt(count);%0A            if (escape) %7B%0A                if (ch == 't') %7B%0A                    field.append('%5Ct');%0A                %7D%0A                else if (ch == 'n') %7B%0A                    field.append('%5Cn');%0A                %7D%0A                else if (ch == 'N') %7B%0A                    isNull = true;%0A                %7D%0A                else if (ch == '%5C%5C') %7B%0A                    field.append('%5C%5C');%0A                %7D%0A                escape = false;%0A            %7D%0A            // Not currently escaped%0A            else %7B%0A                if (ch == '%5C%5C' && POSTGRES) %7B%0A                    escape = true;%0A                %7D%0A                //Neither escaped nor postgres%0A                else %7B%0A                    if (ch == '%5Ct') %7B%0A                        if (isNull) %7B%0A                            data.add(null);%0A                        %7D%0A                        else %7B%0A                            //data.add(field.toString());%0A                            return field.toString();%0A                        %7D%0A//                        field.setLength(0);%0A                        isNull = false;%0A                    %7D%0A                    else %7B%0A                        field.append(ch);%0A                    %7D%0A                %7D%0A%0A            %7D%0A            count++;%0A%0A//            if (count == line.length() && escape) %7B%0A//                line = rd.readLine();%0A//                if (line == null) %7B%0A//                    break;%0A//                %7D%0A//                count = 0;%0A//                escape = false;%0A//            %7D%0A        %7D%0A%0A//        if (isNull)%7B%0A//            data.add(null);%0A//        %7D%0A//        else %7B%0A//            data.add(field.toString());%0A//        %7D%0A        return field.toString();%0A    %7D%0A%0A%0A
 %7D%0A

Move back to master version.