
package org.fda.commands;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.lang.reflect.Field;
import java.util.Calendar;
import org.fda.data.Enums.RunCommand;
import org.fda.data.TimeKeeper;
import org.fda.data.Utilities;

/**
 *
 * @author Gokhan.Yavas
 */
public abstract class Command {
    public RunCommand rcmd;    
    private final TimeKeeper tk = new TimeKeeper(Utilities.cmd_key_word);
    private long beforeUsedMem, afterUsedMem;
    protected double actualUsedMemory;

    public double getActualUsedMemory() {
        return actualUsedMemory;
    }
    private Runtime rt = Runtime.getRuntime();
    public void startMemoryMeasurement(){
        beforeUsedMem = rt.totalMemory()-rt.freeMemory();
    }
    public void endMemoryMeasurement(){
        afterUsedMem = rt.totalMemory()-rt.freeMemory();
        actualUsedMemory = (double)(afterUsedMem-beforeUsedMem)/1024/1024;
    }
    
    public boolean startTimer4Process(String label){
        return tk.addStartTimePoint(label);
    }
    public boolean endTimer4Process(String label){
        return tk.addEndTimePoint(label);
    }    
    public boolean setCommandEnd(){
        return tk.stopTimer();
    }
    public void writeCommand(){                               
        setCommandEnd();
        Field[] fields = this.getClass().getDeclaredFields();        
        try{
            Field cmdfield = this.getClass().getField("rcmd");
            Field destfield;
            try{
                destfield= this.getClass().getDeclaredField("destinationFolder");
                //System.out.println(((File)destfield.get(this)));
                if(((File)destfield.get(this))==null)
                    destfield= this.getClass().getDeclaredField("sourceFolder");
            }
            catch(NoSuchFieldException nsfe){
                destfield= this.getClass().getDeclaredField("sourceFolder");
            }
            destfield.setAccessible(true);
            String fname = ((File)destfield.get(this)).getAbsolutePath()+File.separator+cmdfield.get(this)+"_run_on_"+Calendar.getInstance().getTime().toString().replaceAll("\\s+|:", "_")+".log";
            BufferedWriter bw = new BufferedWriter(new FileWriter(fname));
            bw.append("Command = "+cmdfield.get(this)+Utilities.ls);
            for(Field f : fields){
                f.setAccessible(true);
                if(f.getType().getCanonicalName().equals(File.class.getCanonicalName())){
                    if(f.get(this)!=null)
                        bw.append(f.getName()+ " = "+((File)f.get(this)).getAbsolutePath()+Utilities.ls);  
                    else{                        
                        bw.append(f.getName()+ " = null"+Utilities.ls);  
                    }
                }
                else{
                    bw.append(f.getName()+ " = "+f.get(this)+Utilities.ls);  
                }
            }
            
            bw.append(Utilities.ls);
            bw.append(tk.getPoints());
            bw.append("Memory Usage(in Mb):\t"+Utilities.numberFormatter.format(getActualUsedMemory()));
            bw.close();            
        }
        catch(Exception e){
            e.printStackTrace();
        }
    }
    public void writeCommand(boolean writeLog2Dest){                               
        setCommandEnd();
        Field[] fields = this.getClass().getDeclaredFields();        
        try{
            Field cmdfield = this.getClass().getField("rcmd");
            Field destfield;
            if(writeLog2Dest){
                destfield= this.getClass().getDeclaredField("destinationFolder");
            }
            else{
                destfield= this.getClass().getDeclaredField("sourceFolder");
            }
            destfield.setAccessible(true);
            String fname = ((File)destfield.get(this)).getAbsolutePath()+File.separator+cmdfield.get(this)+"_run_on_"+Calendar.getInstance().getTime().toString().replaceAll("\\s+|:", "_")+".log";
            BufferedWriter bw = new BufferedWriter(new FileWriter(fname));
            bw.append("dnAQET Version = "+Utilities.version+Utilities.ls);
            bw.append("Command = "+cmdfield.get(this)+Utilities.ls);
            for(Field f : fields){
                f.setAccessible(true);
                if(f.getType().getCanonicalName().equals(File.class.getCanonicalName())){
                    if(f.get(this)!=null)
                        bw.append(f.getName()+ " = "+((File)f.get(this)).getAbsolutePath()+Utilities.ls);  
                    else{                        
                        bw.append(f.getName()+ " = null"+Utilities.ls);  
                    }
                }
                else{
                    bw.append(f.getName()+ " = "+f.get(this)+Utilities.ls);  
                }
            }
            bw.append(Utilities.ls);
            bw.append(tk.getPoints());
            bw.append("Memory Usage(in Mb):\t"+Utilities.numberFormatter.format(getActualUsedMemory()));
            bw.close();            
        }
        catch(Exception e){
            e.printStackTrace();
        }
    }
    
}
