package uk.ac.ebi.quickgo.annotation.converter;

import uk.ac.ebi.quickgo.annotation.model.Annotation;

import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.StringJoiner;
import java.util.function.Function;

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

/**
 * Convert an Annotation to the GPAD format.
 *
 * See the format here: http://geneontology.org/page/gene-product-association-data-gpad-format}
 *
 * An except from a GPAD file is below:
 * UniProtKB	A0A000	enables	GO:0003824	GO_REF:0000002	ECO:0000256	InterPro:IPR015421|InterPro:IPR015422		20170107	InterPro		go_evidence=IEA
 * UniProtKB	A0A000	enables	GO:0003870	GO_REF:0000002	ECO:0000256	InterPro:IPR010961		20170107	InterPro		go_evidence=IEA
 * UniProtKB	A0A000	involved_in	GO:0009058	GO_REF:0000002	ECO:0000256	InterPro:IPR004839		20170107	InterPro		go_evidence=IEA
 * UniProtKB	A0A000	enables	GO:0030170	GO_REF:0000002	ECO:0000256	InterPro:IPR004839|InterPro:IPR010961		20170107	InterPro		go_evidence=IEA
 * UniProtKB	A0A000	involved_in	GO:0033014	GO_REF:0000002	ECO:0000256	InterPro:IPR010961		20170107	InterPro		go_evidence=IEA
 *
 * @author Tony Wardell
 * Date: 17/01/2017
 * Time: 11:24
 * Created with IntelliJ IDEA.
 */
public class AnnotationToGPAD extends AnnotationTo implements Function<Annotation, List<String>> {

    static final String OUTPUT_DELIMITER = "\t";

    @Override
    public List<String> apply(Annotation annotation) {
        if (Objects.isNull(annotation.slimmedIds) || annotation.slimmedIds.isEmpty()) {
            return Collections.singletonList(toOutputRecord(annotation, annotation.goId));
        } else {
            return annotation.slimmedIds.stream()
                                        .map(goId -> this.toOutputRecord(annotation, goId))
                                        .collect(toList());
        }
    }

    private String toOutputRecord(Annotation annotation, String goId) {
        StringJoiner tsvJoiner = new StringJoiner(OUTPUT_DELIMITER);
        String[] idElements = idToComponents(annotation);
        return tsvJoiner.add(idElements[0])
                        .add(idElements[1])
                        .add(annotation.qualifier)
                        .add(goId)
                        .add(annotation.reference)
                        .add(annotation.evidenceCode)
                        .add(withFromAsString(annotation.withFrom))
                        .add(annotation.interactingTaxonId)
                        .add(toYMD(annotation.date))
                        .add(annotation.assignedBy)
                        .add(extensionsAsString(annotation.extensions))
                        .add("goEvidence=" + annotation.goEvidence).toString();
    }
}

@@ -2064,16 +2064,30 @@
 notation
+.geneProductId
 );%0A     
@@ -2190,32 +2190,56 @@
            .add(
+nullToEmptyString.apply(
 annotation.quali
@@ -2243,16 +2243,17 @@
 alifier)
+)
 %0A       
@@ -2274,21 +2274,46 @@
    .add(
+nullToEmptyString.apply(
 goId)
+)
 %0A       
@@ -2326,32 +2326,56 @@
            .add(
+nullToEmptyString.apply(
 annotation.refer
@@ -2379,16 +2379,17 @@
 ference)
+)
 %0A       
@@ -2402,32 +2402,56 @@
            .add(
+nullToEmptyString.apply(
 annotation.evide
@@ -2458,16 +2458,17 @@
 nceCode)
+)
 %0A       
@@ -2549,32 +2549,49 @@
            .add(
+Integer.toString(
 annotation.inter
@@ -2604,16 +2604,17 @@
 TaxonId)
+)
 %0A       
@@ -2688,16 +2688,40 @@
    .add(
+nullToEmptyString.apply(
 annotati
@@ -2734,16 +2734,17 @@
 ignedBy)
+)
 %0A       
@@ -2853,16 +2853,40 @@
 nce=%22 + 
+nullToEmptyString.apply(
 annotati
@@ -2899,16 +2899,17 @@
 vidence)
+)
 .toStrin

Replace nulls with empty strings.