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.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
 */
public class KeggDemoConverter extends BioFileConverter
{
    protected static final Logger LOG = Logger.getLogger(KeggDemoConverter.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 KeggDemoConverter(ItemWriter writer, Model model) {
        super(writer, model, "GenomeNet", "KEGG PATHWAY");
    }

    /**
     * Set the taxon id to process.
     * @param taxonId the id
     */
    public void setOrganism(String taxonId) {
        this.taxonId = taxonId;
    }
    
    /**
     * Called for each file found by ant.
     *
     * {@inheritDoc}
     */
    public void process(Reader reader) throws Exception {
        // the organism we are processing is set by the project.xml file with an entry like:
        //      <property name="organism" value="36329"/>
        if (taxonId == null || taxonId.equals("")) {
            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 {
        // this file has data of the format:
        // pathway id | pathway name

        Iterator<String[]> lineIter = FormattedTextParser.parseTabDelimitedReader(reader);

        while (lineIter.hasNext()) {
            // line is an array with one element for each tab separated value in the current line
            String[] line = (String[]) lineIter.next();
            
            String pathwayId = line[0];
            String pathwayName = line[1];
            
            // create or fetch the pathway item and add the name
            Item pathway = getPathway(pathwayId);
            pathway.setAttribute("name", pathwayName);

            // we've now finished with the pathway so we can store it
            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<String[]> lineIter = FormattedTextParser.parseTabDelimitedReader(reader);

        while (lineIter.hasNext()) {
            // line is an array with one element for each tab separated value in the current line
            String[] line = (String[]) lineIter.next();
            
            String geneId = line[0];
            Item gene = createItem("Gene");
            gene.setAttribute("primaryIdentifier", geneId);
            gene.setReference("organism", getOrganism());

            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);
            }
            store(gene);
        }
    }

    
    /**
     * Fetch the organism item - create and store the item on the first time called.
     * @return an Item representing the organism
     */
    private Item getOrganism() throws ObjectStoreException {
        if (organism == null) {
            organism = createItem("Organism");
            organism.setAttribute("taxonId", taxonId);
            store(organism);
        }
        return organism;
    }
    
    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;
    }
}

@@ -3288,372 +3288,8 @@
    %0A
-            String pathwayId = line%5B0%5D;%0A            String pathwayName = line%5B1%5D;%0A            %0A            // create or fetch the pathway item and add the name%0A            Item pathway = getPathway(pathwayId);%0A            pathway.setAttribute(%22name%22, pathwayName);%0A%0A            // we've now finished with the pathway so we can store it%0A            store(pathway);%0A
     
@@ -3286,32 +3286,32 @@
      %0A        %7D%0A
+
     %7D%0A%0A    /**%0A 
@@ -3984,632 +3984,8 @@
    %0A
-            String geneId = line%5B0%5D;%0A            Item gene = createItem(%22Gene%22);%0A            gene.setAttribute(%22primaryIdentifier%22, geneId);%0A            gene.setReference(%22organism%22, getOrganism());%0A%0A            String%5B%5D pathwayIds = line%5B1%5D.split(%22 %22);%0A            %0A            // add each pathway to the Gene.pathways collection%0A            for (String pathwayId : pathwayIds) %7B%0A              // getPathway() will create a new pathway or fetch it from a map if already seen%0A              Item pathway = getPathway(pathwayId);%0A              gene.addToCollection(%22pathways%22, pathway);%0A            %7D%0A            store(gene);%0A
     
@@ -4378,32 +4378,32 @@
 ism);%0A        %7D%0A
+
         return o
@@ -4421,332 +4421,6 @@
   %7D%0A
-    %0A    private Item getPathway(String pathwayId) %7B%0A        Item pathway = pathwayMap.get(pathwayId);%0A        if (pathway == null) %7B%0A            pathway = createItem(%22Pathway%22);%0A            pathway.setAttribute(%22identifier%22, pathwayId);%0A            pathwayMap.put(pathwayId, pathway);%0A        %7D%0A        return pathway;%0A    %7D%0A
 %7D%0A

Remove some code from the Kegg example file.