package com.sun.solarisinstall.postinstall.tasks;

import java.io.*;
import java.util.*;
import com.sun.install.*;
import com.sun.wizards.core.*;
import com.sun.wizards.builder.resolver.*;
import com.sun.install.products.*;
import com.sun.solarisinstall.*;
import com.sun.solarisinstall.panels.*;
import com.sun.solarisinstall.postinstall.*;

/**
 * The BuildProdTreeTask builds a product tree at run time. It precedes
 * the ProductTask in the install sequence. In its perform method,
 * it collects information about the packages/patches/run command scripts
 * to be installed, then dynamically constructs the necessary product tree 
 * and adds the tree to the install sequence.
 */
public class BuildProdTreeTask extends Task implements Serializable
{
  /**
   * Create a BuildProdTree task
   *
   */
  public BuildProdTreeTask()
  {
  }

  /**
   * Perform this Task.
   *
   * This method is used to build a product task tree at run time
   */
  public void perform()
    {
      Sequence sequence = getSequence();
      WizardState wizardState = sequence.getState();
      WizardState rootState = wizardState.getRootWizardState();
      
      if (wizardState.getPurpose().equals("uninstall"))
        return;	// just skip this task if uninstalling

      Product product = (Product)wizardState.getData(InstallConstants.productTree);
      Vector installUnits =  (Vector)rootState.getData(ProfileConstants.InstallTags);
      String productDir = (String)rootState.getData(ProfileConstants.OSDirectory);
      String productName = 
	new String(MsgCat.getString("com.sun.solarisinstall.SolarisInstall",
				    SolarisInstallResources.MSG_ADDITIONAL_SW));
      Object[] msgargs = {productName};
      String label = new String(MsgCat.getString("com.sun.install.Install", 
			 InstallResources.MSG_INSTALL_FRAME_TITLE, msgargs));

      updateLabel(label);
      if (installUnits == null || productDir == null)
        return;	// nothing to do

      Vector selectedComponentIDs = new Vector();
      /*
       * now build up the product task tree
       */

      /* The actual package leaf.  Take a look at the PkgUnit javadoc
       * to see what arguments you need to provide (Briefly, they are
       * ProductName, RelativeDirectory, PackageName,
       * RelativeDirectory for response file, and a possible
       * Destination table
       */
      int numUnits = installUnits.size();

      if (Def.DEBUG) {
	System.out.println("BuildProdTreeTask numUnits = " + numUnits);
      }

      if (numUnits > 0) {
        SoftwareComponent swComponent =
          new SoftwareComponent(new Msg("Solaris Packages/Patches"));
        swComponent.setProperty("isRequired", new Boolean(true));
        swComponent.setProperty("isDefault", new Boolean(true));
        selectedComponentIDs.addElement(
          swComponent.getComponentName().toString());
        product.addComponent(swComponent);

        for (int index = 0; index < numUnits; index++) {
          InstallTag unitTag = (InstallTag)installUnits.elementAt(index);
          // parse file name
          File installFile = new File(unitTag.getName());
          String installName = installFile.getName();
          String installDir;
          if (installFile.getParent() != null)
            installDir = installFile.getParent();
          else
            installDir = File.separator;
          if (unitTag.getType().equals("script")) {
            ScriptUnit rcFiles = new ScriptUnit();
            swComponent.addComponent(rcFiles);
            if (!installFile.isAbsolute()) {
              if (installFile.getParent() != null)
                installDir = productDir + File.separator + "scripts" +
                  File.separator + installFile.getParent();
              else
                installDir = productDir + File.separator + "scripts";
            }
            rcFiles.addFile(installDir, installName, null);
            if (Def.DEBUG) {
	      System.out.println("Script: ");
      	    }
          } else if (unitTag.getType().equals("package")) {
            if (!installFile.isAbsolute()) {
              if (installFile.getParent() != null)
                installDir = productDir + File.separator + "packages" +
                  File.separator + installFile.getParent();
              else
                installDir = productDir + File.separator + "packages";
            }
            PkgUnit solarisPkg = new PkgUnit(
              installDir,	// relative path
              installName);	// package name
            swComponent.addComponent(solarisPkg);
            if (Def.DEBUG) {
	      System.out.print("Package: ");
      	    }
          } else if (unitTag.getType().equals("patch")) {
            if (!installFile.isAbsolute()) {
              if (installFile.getParent() != null)
                installDir = productDir + File.separator + "patches" +
                  File.separator + installFile.getParent();
              else
                installDir = productDir + File.separator + "patches";
            }
            PatchUnit solarisPch = new PatchUnit(installDir, installName);
            swComponent.addComponent(solarisPch);
            if (Def.DEBUG) {
	      System.out.print("Patch: ");
      	    }
          }
          if (Def.DEBUG) {
            System.out.println("Install dir is " + installDir);
            System.out.println("Install name is " + installName);
          }
        }
      }

      wizardState.setData(InstallConstants.selectedComponents, selectedComponentIDs);

      // This is normally done when the sequence is deserialized from
      // the archive. As we are building the product tree dynamically,
      // We need to repeat it here to initialize the components just
      // added
      product.initialize(wizardState);
    }

  /* Sets the progress label on the fly */
  public void updateLabel(String label)
    {
      
      getSequence().getState().callClientObjectMethod(getSequence().getCallerRoute().copy(), 
				   "setLabel",
				   new String[] {"java.lang.String.class" },
				   new Object[] { label });
    }
  
  /**
   * Add the runtime class requirements to the specified vector.
   * @param resourceVector The vector containing all the required resources
   *     for this wizard.
   */
  public void addRuntimeResources(Vector resourceVector)
  {
    super.addRuntimeResources(resourceVector);

    resourceVector.addElement(new String[] {null, 
	"com.sun.solarisinstall.SolarisInstallResources"});

    resourceVector.addElement(new String[] {null, 
	"com.sun.solarisinstall.postinstall.tasks.InstallTag"});

    resourceVector.addElement(new String[] {null, 
	"com.sun.solarisinstall.postinstall.tasks.BuildProdTreeTask"});

    resourceVector.addElement(new String[] {null, 
	"com.sun.solarisinstall.postinstall.tasks.ScriptUnit"});

    resourceVector.addElement(new String[] {null, 
	"com.sun.wizards.builder.resolver.ResourceInputStream"});
  }
}
