package com.sun.launcher.tasks;

import java.io.*;
import java.util.*;
import java.text.SimpleDateFormat;
import com.sun.wizards.core.*;
import com.sun.install.tasks.*;
import com.sun.install.products.*;
import com.sun.launcher.*;
import com.sun.launcher.core.*;
import com.sun.launcher.tasks.*;


/** InitTask: A task to read the file used to drive 
*                 the launcher and initialize data.
*
* @version @(#)InitTask.java	1.8 99/10/08 12:31:59  */

public class InitTask extends Task implements Serializable
{
  private static Hashtable launchTable = new Hashtable();
  private String launchfile = null;
  private boolean OK_TO_USE_VOLD = true;

  /*
   * This happens at build time. 
   */
  public InitTask(String launchfile, boolean vold)
  {
    this.launchfile = launchfile;  // the dispatch_table
    OK_TO_USE_VOLD = vold;
  }

  public InitTask(boolean vold)
  {
    OK_TO_USE_VOLD = vold;
  }

  /** 
   *  Read the file
   */
  public void perform()
  {
    WizardState state = getSequence().getState();

    /*
     *  Run bpgetfile and save results for later.
     */
    String output = LaunchServerObject.runBPgetfile();
    state.setData(LaunchConstants.bpOutput, output);

    /*
     *  Determine if we're in the mini-root by checking for
     *  /.tmp_proto file.
     */
    File dotTmpProto = new File("/.tmp_proto");
    boolean miniRoot = true;
    if (dotTmpProto.exists() && dotTmpProto.isDirectory()) {
      state.setData(LaunchConstants.miniRoot, Boolean.TRUE);
      if (Def.DEBUG) System.out.println("InitTask: miniRoot set to TRUE" );
      miniRoot = true;
    } else {
      /*
       * create .running directory to tell rc script that we should
       * restart launcher if reboot occurs. IterNode later deletes
       * .running dir
       */
      LaunchServerObject.createDir(LaunchConstants.VarSadmWebstart + "/" 
                                  + LaunchConstants.running);
      state.setData(LaunchConstants.miniRoot, Boolean.FALSE);
      if (Def.DEBUG) System.out.println("InitTask: miniRoot set to FALSE" );
      miniRoot = false;
    }


    if (launchfile == null) {    // no longer set by constructor
      this.launchfile = "dispatch_table";  
    }
    if (Def.DEBUG) System.out.println("InitTask: file = " +launchfile);
    state.setData(LaunchConstants.launchFile, launchfile);

    /*
     *  See if there is an empty dir indicating that we've skipped
     *  non-miniroot product(s).
     */
    String skippedAfter = LaunchConstants.skippedAfterDir;
    File skippedAfterDir = new File(skippedAfter);
    if (skippedAfterDir.exists()) {
      state.setData(LaunchConstants.skippedAfter, Boolean.TRUE);
      if (Def.DEBUG) System.out.println("InitTask: FOUND skippedAfter dir");
    } else {
      state.setData(LaunchConstants.skippedAfter, Boolean.FALSE);
      if (Def.DEBUG) System.out.println("InitTask: NO skippedAfter dir");
    }

    /*
     *  See if there is an empty dir indicating that a previous run
     *  of the launcher found non-miniroot products to install
     */
    String haveAfter = LaunchConstants.haveAfterDir;
    File haveAfterDir = new File(haveAfter);
    if (haveAfterDir.exists()) {
      state.setData(LaunchConstants.haveAfter, Boolean.TRUE);
      if (Def.DEBUG) System.out.println("InitTask: FOUND haveAfter dir");
    } else {
      state.setData(LaunchConstants.haveAfter, Boolean.FALSE);
      if (Def.DEBUG) System.out.println("InitTask: NO haveAfter dir");
    }


    if (OK_TO_USE_VOLD) {
      if (LaunchServerObject.isVoldAlive(state)) {
        if (Def.DEBUG) System.out.println("InitTask: USING VOLD");
        MountCDTask.setVold(true);
        state.setData(LaunchConstants.usingVold, Boolean.TRUE);
      } else {
        if (Def.DEBUG) System.out.println("InitTask: Not Using Vold, no proc");
        state.setData(LaunchConstants.usingVold, Boolean.FALSE);
      }
    } else {
      state.setData(LaunchConstants.usingVold, Boolean.FALSE);
        if (Def.DEBUG)System.out.println("InitTask: Not Using Vold per define");
    }
   
    /*
     * Read find_device.out to get cdrom device. store in wizardstate
     */
    String finddevPath = "find_device.out";
    File findDevFile = new File(finddevPath);
    if (!findDevFile.exists()) {
      Object[] findDeviceArg = { finddevPath };
      System.out.println(MsgCat.getString("com.sun.launcher.Launcher",
                              LauncherResources.MSG_EXITING_FILE_DOES_NOT_EXIST,
                              findDeviceArg));
      state.exit(98);
    }
    String device = 
        LaunchServerObject.readLineofFile(finddevPath);
    if (Def.DEBUG) System.out.println("\nInitTask cdrom device: " + device); 

    state.setData(LaunchConstants.CDid, device);
    state.setData(LaunchConstants.CDdevice, "/dev/dsk/" + device);
    state.setData(LaunchConstants.CDdeviceRaw, "/dev/rdsk/" + device);
    state.setData(LaunchConstants.CDmount, "/cdrom2");
    state.setData(LaunchConstants.voldStopped, Boolean.FALSE);

    /*
     * if system has rebooted, may need to finish befores 
     */
    String minicomplete = LaunchConstants.mrInstallsCompleteFile;
    File minicompleteFile = new File(minicomplete); 
    if (minicompleteFile.exists()) {
      if (Def.DEBUG) {
        System.out.println("InitTask: minirootComplete file found");
      }
      state.setData(LaunchConstants.beforesDone, Boolean.TRUE);

    } else {
      state.setData(LaunchConstants.beforesDone, Boolean.FALSE);
    }
    String chkpt = LaunchConstants.chkptFile;
    File chkPtFile = new File(chkpt); 

    if (chkPtFile.exists()) {
      String progress = LaunchServerObject.readLineofFile(chkpt);
      /*
       * Setting the progress variable will signal IterNode to
       * artificially set the LoopNode Iteration key, so we can
       * resume installation from where we left off. Note that we'll
       * have to set the Iteration key to (progress + 1),
       * since progress indicates which installers have completed.
       */
      if (! miniRoot) {
        /*
         * if we finished with the befores in the miniroot, startover
         */
        if (Def.DEBUG) {
          System.out.println("InitTask: Checkpoint after reboot, " +
                                          "progress=" + progress);
        }
        if (! progress.equals("0")) {
          state.setData(LaunchConstants.progress, new Integer(progress));
        }
      } else {
        //
        // this really shouldn't happen, maybe exit??
        //
        if (Def.DEBUG) {
          System.out.println("InitTask: Found checkpoint file in miniRoot" +
                              ", contents=" + progress);
        }
        state.setData(LaunchConstants.progress, new Integer(progress));
      }
    } else {
      updateCheckpoint("0");
    }


    /*
     * Initialize skip cd panel to not skip
     */
    state.setData(LaunchConstants.SkipCDPanel, Boolean.FALSE);


    /*
     * Read the file. If file is empty, exit.
     */
    launchTable = readLaunchFile(launchfile);
    /*
     * Empty launch table is now ok, to get Reboot panel in miniroot
     */
    //if (launchTable.isEmpty()) {
    //  Object[] launchFileArg = { launchfile };
    //  System.out.println(MsgCat.getString("com.sun.launcher.Launcher",
    //                          LauncherResources.MSG_EXITING_LAUNCHER,
    //                          launchFileArg));
    //  state.exit(99);
    //}
    state.setData(LaunchConstants.launchTable, launchTable);
    
    /*
     * Set up log file
     */
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy'_'MM'_'dd'_'HHmm");
    Date date = new Date();
    String logdir = "/var/sadm/system/logs/";
    if (miniRoot) logdir = "/a/var/sadm/system/logs/";
    String logname = "webstart_launch.log_" + sdf.format(date);
    state.setData(LaunchConstants.logName, logdir + logname);

    sdf = new SimpleDateFormat("yyyy.MM.dd, HH:mm z");
    String timestamp = sdf.format(date);
    Object[] dateArg= { timestamp };
    LaunchServerObject.writeToLog(logdir + logname, 
                MsgCat.getString("com.sun.launcher.Launcher",
                                 LauncherResources.MSG_LOG_LAUNCHER_TIMESTAMP,
                                 dateArg));
  }


  /*
   * Updates checkpoint file. String passed in should contain
   * a number representing the "W" number in the dispatch_table
   * of the cd completed.
   */
  public static void updateCheckpoint(String statusline ) 
  {
    String chkpt = LaunchConstants.chkptFile;
    File chkPtFile = new File(chkpt);

    if ( chkPtFile.exists()) chkPtFile.delete();
    try {
      FileWriter log = new FileWriter(chkpt);
      PrintWriter propfile = new PrintWriter(log);
      propfile.println(statusline);
      if (Def.DEBUG) System.out.println("updating checkpoint to: " +statusline);
      propfile.close();
    } catch (IOException ex) {
        System.out.println("InitTask: updateCheckpoint IOException: " + ex);
    }
  }


  /*
   *  Reads dispatch_table and returns Hashtable containing attributes
   */
  public static Hashtable readLaunchFile(String LaunchFile) 
  {
    boolean done = false;
    BufferedReader launch;
    FileInputStream launchStream;
    Hashtable hash = new Hashtable();

    if (Def.DEBUG) System.out.println("readLaunchFile: launchfile="+LaunchFile);
    File launchFile= new File(LaunchFile);
    try {
        launchStream = new FileInputStream(launchFile);
        launch = new BufferedReader(new InputStreamReader(launchStream));
    } catch(IOException e) {
        System.out.println("Error opening file " +
                           launchFile.getPath() +
                           ".");
        return(hash);
    }
    while (!done) {
      try {
        String line = launch.readLine();
        if (line==null)
          done = true;
        else {
          int equalsPosition = line.indexOf('=');
          if (equalsPosition > 0) {
            String attribute = line.substring(0, equalsPosition);
            String value = line.substring(equalsPosition+1);

       //System.out.println("launchinfo: attribute="+attribute+" value="+value);

            hash.put(attribute, value);

          }
        }
      } catch (IOException ex) {
        done = true;
        System.err.println("Error reading file " +
                           launchFile.getPath() + ".");
      }
    }
    try {
        launchStream.close();
    } catch(IOException e) {
    }

    return(hash);
  }


  /**
   * Add the runtime class requirements to the specified vector.
   */
  public void addRuntimeResources(Vector resourceVector)
  {
    resourceVector.addElement(new String[] {null, "com.sun.launcher.tasks.InitTask"});
    resourceVector.addElement(new String[] {null, "com.sun.install.products.RunCmd"});
  }

}
