/* 
 *    FlowManager.java 
 *    Copyright (C) 2012-2013 Aristotle University of Thessaloniki, Greece 
 */
package dbn; 
  
import dbn.data.DBNFile;
import dbn.data.OptionsHandler;
  
/** 
 * A control class that manages the user's arguments, prints the output and 
 * handles the flow of the main task. It contains the <code>main</code> method that 
 * organizes the data flow. 
 * 
 * @see LearningManager
 * @see PredictionManager
 * @author Evripidis Gkanias 
 */
public class FlowManager { 
      
    /** 
     * Gets the user's options and returns the {@link OptionsHandler}, to let 
     * the handler use them. 
     *  
     * @param args the user's options 
     * @return the handler of the options 
     * @throws NullPointerException 
     */
    public static OptionsHandler ParseArguments(String[] args) { 
        if (args == null || args.length <= 0) throw new NullPointerException("Options are not set!"); 
          
        OptionsHandler ahandler = new OptionsHandler(); 
        try { 
            ahandler.setArgs(args); 
        } catch (Exception ex) { 
            System.err.println("Options error!"); 
        } 
          
        return ahandler; 
    } 
      
    /** 
     * Converts the milliseconds to  
     * <code>[Hours]:[Minutes]:[Seconds].[Tenths of Seconds]</code> 
     * {@link String} format.
     *  
     * @param milliseconds the duration in milliseconds
     * @return the duration formatted to <code>Sting</code> showing hours, minutes and seconds
     */
    public static String FormatMilliseconds(long milliseconds) { 
        long hours   = milliseconds/3600000; 
        milliseconds = milliseconds%3600000; 
        long minutes = milliseconds/60000; 
        milliseconds = milliseconds%60000; 
        long seconds = milliseconds/1000; 
        milliseconds = milliseconds%1000; 
          
        return String.format("%d:%d:%d.%d", hours, minutes, seconds, milliseconds/100); 
    } 
      
    /** 
     * The method that takes as input the user's options and manages the data flow
     * of the project.
     * 
     * @param args the command line arguments 
     */
    public static void main(String[] args) throws Exception {
        OptionsHandler ah = ParseArguments(args); 
          
        System.out.println("1/3 Train DBN"); 
        LearningManager lm = new LearningManager(); 
        lm.SetLearnerParameters(ah); 
        long trainingDuration = lm.startLearning(); 
        System.out.println("Training time: " + FormatMilliseconds(trainingDuration)); 
          
        System.out.println(""); 
        System.out.println("2/3 Save DBN"); 
        long start = System.currentTimeMillis(); 
        String dbnFileName = OptionsHandler.GetFileName( 
                ah.getTrainPath());
        dbnFileName = dbnFileName.replace("-train", ""); 
        String dbnFileLocation = "DATA/" + dbnFileName + ".dbn"; 
        DBNFile.SaveToFile(lm.getDBLearner().getLeanedDBN(), dbnFileLocation); 
        
        System.out.println("DBN saved in file: " + dbnFileLocation);
        System.out.println("Saving time: " + FormatMilliseconds(System.currentTimeMillis() - start)); 
          
        System.out.println(""); 
        System.out.println("3/3 Test Data"); 
        PredictionManager pm = new PredictionManager(); 
        long testingDuration = pm.TestData(lm.getLearner(), ah.getTestSet()); 
        System.out.println("Testing time: " + FormatMilliseconds(testingDuration)); 
    } 
}