package org.intermine.bio.dataconversion;

/*
 * Copyright (C) 2002-2010 FlyMine
 *
 * This code may be freely distributed and modified under the
 * terms of the GNU Lesser General Public Licence.  This should
 * be distributed with the code.  See the LICENSE file for more
 * information or http://www.gnu.org/copyleft/lesser.html.
 *
 */

import java.io.File;
import java.io.IOException;
import java.io.Reader;
import java.util.HashMap;
import java.util.Iterator;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.intermine.dataconversion.ItemWriter;
import org.intermine.metadata.Model;
import org.intermine.objectstore.ObjectStoreException;
import org.intermine.util.FormattedTextParser;
import org.intermine.xml.full.Item;


/**
 * DataConverter to load Kegg Pathways and link them to Genes
 *
 * @author Richard Smith
 */
public class KeggExampleConverter extends BioFileConverter
{
    protected static final Logger LOG = Logger.getLogger(KeggExampleConverter.class);

    protected HashMap<String, Item> pathwayMap = new HashMap<String, Item>();
    private String taxonId = null;
    private Item organism = null;

    /**
     * Constructor
     * @param writer the ItemWriter used to handle the resultant items
     * @param model the Model
     */
    public KeggExampleConverter(Model model, ItemWriter writer) {
        super(writer, model, "GenomeNet", "KEGG PATHWAY");
    }

    /**
     * Set the taxon id to process.
     * @param taxonId the id
     */
    public void setTaxonId(String taxonId) {
        this.taxonId = taxonId;
    }

    /**
     * Called for each file found by ant.
     *
     * {@inheritDoc}
     */
    public void process(Reader reader) throws Exception {
        if (StringUtils.isEmpty(taxonId)) {
            throw new IllegalArgumentException("No taxonId provided: " + taxonId);
        }

        // There are two files:
        //              map_title.tab - pathway ids and their names
        //      xxx_gene_map.tab - genes and the pathways they are involved in
        // The following code works out which file we are reading and calls the corresponding method
        File currentFile = getCurrentFile();

        if (currentFile.getName().equals("map_title.tab")) {
            processMapTitleFile(reader);
        } else if (currentFile.getName().endsWith("gene_map.tab")) {
            processGeneMapFile(reader);
        } else {
            throw new IllegalArgumentException("Unexpected file: " + currentFile.getName());
        }
    }


    /**
     * Process all rows of the map_title.tab file
     * @param reader a reader for the map_title.tab file
     * @throws IOException
     * @throws ObjectStoreException
     */
    private void processMapTitleFile(Reader reader) throws IOException, ObjectStoreException {
        Iterator lineIter = FormattedTextParser.parseTabDelimitedReader(reader);

        // this file has data of the format:
        // pathway id | pathway name
        while (lineIter.hasNext()) {
            // line is a string array with the one element for each tab separated value
            // on the next line of the file
            String[] line = (String[]) lineIter.next();

            String pathwayId = line [0];
            String pathwayName = line[1];

            // getPathway will create an Item or fetch it from a map if seen before
            Item pathway = getPathway(pathwayId);
            pathway.setAttribute("name", pathwayName);

            // once we have set the pathway name that is all the information needed so we can store
            store(pathway);
        }
    }

    /**
     * Process all rows of the xxx_gene_map.tab file
     * @param reader a reader for the xxx_gene_map.tab file
     * @throws IOException
     * @throws ObjectStoreException
     */
    private void processGeneMapFile(Reader reader) throws IOException, ObjectStoreException {
        // this file has data of the format:
        // gene id | pathway ids (space separated)

        Iterator lineIter = FormattedTextParser.parseTabDelimitedReader(reader);

        while (lineIter.hasNext()) {
            // line is a string array with the one element for each tab separated value
            // on the next line of the file
            String[] line = (String[]) lineIter.next();

            String geneId = line[0];

            // create a gene with this id as primaryIdentifier
            Item gene = createItem("Gene");
            gene.setAttribute("primaryIdentifier", geneId);
            gene.setReference("organism", getOrganism());

            // split the space separated list of pathway ids
            String[] pathwayIds = line[1].split(" ");

            // add each pathway to the Gene.pathways collection
            for (String pathwayId : pathwayIds) {
                // getPathway() will create a new pathway or fetch it from a map if already seen
                Item pathway = getPathway(pathwayId);
                gene.addToCollection("pathways", pathway);
            }

            // we have finished with this gene now so can store it
            store(gene);
        }
    }

    /**
     * Create a new pathway Item or fetch from a map if it has been seen before
     * @param pathwayId the id of a KEGG pathway to look up
     * @return an Item representing the pathway
     */
    private Item getPathway(String pathwayId) {
        Item pathway = pathwayMap.get(pathwayId);
        if (pathway == null) {
            pathway = createItem("Pathway");
            pathway.setAttribute("identifier", pathwayId);
            pathwayMap.put(pathwayId, pathway);
        }
        return pathway;
    }

    /**
     * Get an Item representing an organism, create and store it if called for the first time
     * @return an Item representing the organism
     * @throws ObjectStoreException
     */
    private Item getOrganism() throws ObjectStoreException {
        if (organism == null) {
            organism = createItem("Organism");
            organism.setAttribute("taxonId", taxonId);
            store(organism);
        }
        return organism;
    }
}

@@ -338,29 +338,8 @@
 */%0A%0A
-import java.io.File;%0A
 impo
@@ -358,24 +358,24 @@
 OException;%0A
+
 import java.
@@ -1160,16 +1160,24 @@
 structor
+.%0A     *
 %0A     * 
@@ -1860,673 +1860,51 @@
   %7D%0A
-%0A        // There are two files:%0A        //              map_title.tab - pathway ids and their names%0A        //      xxx_gene_map.tab - genes and the pathways they are involved in%0A        // The following code works out which file we are reading and calls the corresponding method%0A        File currentFile = getCurrentFile();%0A%0A        if (currentFile.getName().equals(%22map_title.tab%22)) %7B%0A            processMapTitleFile(reader);%0A        %7D else if (currentFile.getName().endsWith(%22gene_map.tab%22)) %7B%0A            processGeneMapFile(reader);%0A        %7D else %7B%0A            throw new IllegalArgumentException(%22Unexpected file: %22 + currentFile.getName());%0A        %7D
+        processGeneMapFile(reader);
 %0A    %7D%0A%0A
 %0A   
@@ -1899,17 +1899,16 @@
 %0A    %7D%0A%0A
-%0A
     /**%0A
@@ -1942,1098 +1942,8 @@
 the 
-map_title.tab file%0A     * @param reader a reader for the map_title.tab file%0A     * @throws IOException%0A     * @throws ObjectStoreException%0A     */%0A    private void processMapTitleFile(Reader reader) throws IOException, ObjectStoreException %7B%0A        Iterator lineIter = FormattedTextParser.parseTabDelimitedReader(reader);%0A%0A        // this file has data of the format:%0A        // pathway id %7C pathway name%0A        while (lineIter.hasNext()) %7B%0A            // line is a string array with the one element for each tab separated value%0A            // on the next line of the file%0A            String%5B%5D line = (String%5B%5D) lineIter.next();%0A%0A            String pathwayId = line %5B0%5D;%0A            String pathwayName = line%5B1%5D;%0A%0A            // getPathway will create an Item or fetch it from a map if seen before%0A            Item pathway = getPathway(pathwayId);%0A            pathway.setAttribute(%22name%22, pathwayName);%0A%0A            // once we have set the pathway name that is all the information needed so we can store%0A            store(pathway);%0A        %7D%0A    %7D%0A%0A    /**%0A     * Process all rows of the 
 xxx_
@@ -1951,32 +1951,40 @@
 ene_map.tab file
+.%0A     *
 %0A     * @param r
@@ -3513,16 +3513,24 @@
 n before
+.%0A     *
 %0A     * 
@@ -3964,24 +3964,24 @@
  %7D%0A%0A    /**%0A
-
      * Get a
@@ -4061,16 +4061,24 @@
 rst time
+.%0A     *
 %0A     * 

update converter to only process genes file