/*
 * P2Psum.java
 *
 * Created on May 2, 2005, 7:20 PM
 */

package DDMT.Nodes;

import java.util.Vector;
import java.io.*;
import jade.lang.acl.*;
import java.util.regex.*;
import DDMT.Agents.NodeAgent.AgentInterface;//not initial

/**
 *
 * @author  jk3
 */
public class P2Psum extends NodeCode{
    
    //Define patterns for integers, strings, doubles, first string, and last string
    private Pattern integerP = Pattern.compile("\\d+");
    private Pattern doubleP = Pattern.compile("\\d+\\p{Punct}\\d+");
    private Pattern stringP = Pattern.compile("\\S+\\s");
    private Pattern alphaStringP = Pattern.compile("[a-zA-Z]\\S*");
    private Pattern neighborP = Pattern.compile("\\s\\d+\\s\\d+\\p{Punct}\\d+");
    private Pattern fileP = Pattern.compile("\\S+\\s\\S+");
    private Pattern firstP = Pattern.compile("\\A\\S+");
    private Pattern lastP = Pattern.compile("\\S+\\Z");
    private Pattern middleP = Pattern.compile("\\s\\S+\\s");
    private Pattern relationP = Pattern.compile("\\A@[Rr][Ee][Ll][Aa][Tt][Ii][Oo][Nn]");
    private Pattern attributeTypeP = Pattern.compile("\\A@[Aa][Tt][Tt][Rr][Ii][Bb][Uu][Tt][Ee]\\s+\\S+\\s+\\S+");
    private Pattern attributeP = Pattern.compile("\\[S^,]*");
    private Pattern heteroDistP = Pattern.compile("\\s(\\S+)");
    private Matcher heteroDistM;
    private Matcher attributeM;
    private Matcher attributeTypeM;
    private Matcher relationM;
    private Matcher fileM;
    private Matcher firstM;
    private Matcher lastM;
    private Matcher middleM;
    private Matcher integerM;
    private Matcher doubleM;
    private Matcher stringM;
    private Matcher alphaStringM;
    private Matcher neighborM;
    
    //Array of data
    Vector data;
    
    //Bool for the sending status for this agent
    boolean sent = false;
    
    //num replied
    int numReplied = 0;
    
    //The one who asked me first
    int asked;
    
    //The sum
    int total = 0;
    
    //the number of clock cycles
    int cycles = 0;
    
    /** Creates a new instance of P2Psum
     -- Can't do anything in here! --
     */
    public P2Psum() {
    }
    
    public void start(){
        //Add up all the data
        
        
        if( this.getNumber() == 40)
        {
            this.openFile();
            
            //System.out.println("Starting the p2p sum...");
            asked = 40;
            Vector nbors = this.getNeighbors();
            sent = true;
            numReplied = nbors.size();
            //iface.printMessage(""+numReplied);
            for( int i= 0; i<nbors.size(); i++)
            {
                iface.sendMessage("send", ((Neighbor)nbors.elementAt(i)).getNumber());
                //iface.printMessage("sending to "+((Neighbor)nbors.elementAt(i)).getNumber());
                
            }
        }
    }
    
    
    public void run(String m, int num)
    {
        
        //iface.printMessage("got message "+m);
        if( m.equals("send"))
        {
            if( sent )
            {
                iface.sendMessage( "0", num);
            }else
            {
                asked = num;
                sent = true;
                Vector nbors = this.getNeighbors();
                numReplied = nbors.size();
                for( int i= 0; i<nbors.size(); i++)
                {
                    iface.sendMessage("send", ((Neighbor)nbors.elementAt(i)).getNumber());
                    //iface.printMessage("sending to "+((Neighbor)nbors.elementAt(i)).getNumber());
                } 
            }
        }
        else
        {
            numReplied--;
            if( total < Integer.parseInt(m))
                total = Integer.parseInt(m);
            
            //iface.printMessage(m+"; "+numReplied);
            
            if( numReplied == 0 )
            {
                //iface.printMessage("Int. node done: "+total);
                if( asked == this.getNumber() )
                {
                    iface.printMessage("Got all of them "+ total );
                }else
                {
                    iface.sendMessage(""+ (total+1), asked );
                }
            }
        }
    }
    /**
     *Method to open a data file
     */
    private void openFile()
    {
        data = new Vector();
        //Delete the old file
        //System.out.println(this.getDataLocation());
        File file = new File(this.getDataLocation());
        
        //Update display
        Vector attributeNames = new Vector();
        int numTuples = 0;
        try{
            
            //Pattern that will be defined for a tuple
            Pattern tupleP = null;
            Matcher tupleM;

            //Read the data types
            FileReader reader = new FileReader(file);
            BufferedReader bReader = new BufferedReader(reader);
            String line = bReader.readLine();
            boolean allAttributes = false; //Boolean that shows whether or not all the attributes have been read
            while(line != null)
            {
                //Find the attribute names and put them in the list
                attributeTypeM = attributeTypeP.matcher(line);
                if( attributeTypeM.matches() )
                {
                    middleM = middleP.matcher(line);
                    middleM.find();
                    Pattern midP = Pattern.compile("\\s+(.+)\\s+");
                    Matcher midM = midP.matcher(middleM.group());
                    midM.find();
                    attributeNames.add(midM.group(1));
                        
                }
                
                //If the line isn't an attribute but there are attributes in the system, then assume that we have all the attributes and generate the pattern.
                else if( attributeNames.size() > 0 && allAttributes == false )
                {
                    allAttributes = true;
                    
                    //Define the tuple
                    String output = new String("(\\s+)?\\S+");
                    for( int i = 1; i< attributeNames.size(); i++)
                    {
                        output = output + "\\s+\\S+";
                    }
                    tupleP = Pattern.compile(output);
                }
                
                //If all the attributes have been read in and the line is a tuple, then...
                else if( tupleP != null )
                {
                    tupleM = tupleP.matcher(line);
                    if( tupleM.find() )
                    {
                        if( !line.equals("@DATA") )
                        {
                            data.addElement(new Integer(Integer.parseInt(line)));
                        }
                    }
                }
                
                line = bReader.readLine();
            }
            reader.close();
            bReader.close();
                
        }catch(IOException ex)
        {
            System.out.println("Error reading local data file!");
            ex.printStackTrace();
        }
    }
}
