/** @param args */
  public static void main(String[] args) {
    String user = "******";
    String view = "build";
    String toolset = "csg_rev18";
    MasterMgrClient client = new MasterMgrClient();
    Wrapper w = null;
    String project = "lr";

    try {
      w = new Wrapper(user, view, toolset, client);
      PluginMgrClient.init();
    } catch (PipelineException e1) {
      e1.printStackTrace();
    }

    String baseModel = "/projects/lr/assets/prop/asylianHelmet/asylianHelmet";
    String finalizeMel = "/projects/lr/assets/tools/mel/finalize-character";

    int pass = 3;

    LinkedList<String> toAdd = new LinkedList<String>();
    for (int i = 2; i <= 10; i++) {
      toAdd.add("asylianHelmet" + i);
    }
    if (pass == 1) {
      try {
        SonyAsset baseAsset = SonyConstants.stringToAsset(w, baseModel);
        Globals.getNewest(
            w, baseAsset.finalScene, CheckOutMode.OverwriteAll, CheckOutMethod.AllFrozen);
        Globals.getNewest(
            w, baseAsset.lr_finalScene, CheckOutMode.OverwriteAll, CheckOutMethod.AllFrozen);

        AssetType baseType = baseAsset.assetType;

        for (String name : toAdd) {
          TreeSet<String> addedNodes = new TreeSet<String>();
          try {
            SonyAsset as = new SonyAsset(project, name, baseType);

            log(as.texGroup + " : ");
            if (!Globals.doesNodeExists(w, as.texGroup)) {
              logLine("Building");
              NodeMod mod = Globals.registerNode(w, as.texGroup, null, Plugins.editorKWrite(w));
              addedNodes.add(as.texGroup);
              BaseAction act = Plugins.actionListSources(w);
              mod.setAction(act);
              doReqs(mod);
              client.modifyProperties(user, view, mod);
            } else logLine("Already Exists");

            log(as.matScene + " : ");
            if (!Globals.doesNodeExists(w, as.matScene)) {
              logLine("Building");
              NodeMod mod = Globals.registerNode(w, as.matScene, "ma", Plugins.editorMaya(w));
              addedNodes.add(as.matScene);
              BaseAction act = Plugins.actionMayaReference(w);
              Globals.referenceNode(w, as.matScene, baseAsset.rigScene, act, REF, "rig");
              client.link(user, view, as.matScene, as.texGroup, REF, LINKALL, null);
              mod.setAction(act);
              doReqs(mod);
              client.modifyProperties(user, view, mod);
            } else logLine("Already Exists");

            log(as.finalScene + " : ");
            if (!Globals.doesNodeExists(w, as.finalScene)) {
              logLine("Building");
              NodeMod mod = Globals.registerNode(w, as.finalScene, "ma", Plugins.editorMaya(w));
              addedNodes.add(as.finalScene);
              BaseAction act = Plugins.actionMayaImport(w);
              Globals.referenceNode(w, as.finalScene, as.matScene, act, DEP, "mat");
              client.link(user, view, as.finalScene, finalizeMel, DEP, LINKALL, null);
              act.setSingleParamValue("ModelMEL", finalizeMel);
              mod.setAction(act);
              doReqs(mod);
              client.modifyProperties(user, view, mod);
            } else logLine("Already Exists");

            log(as.lr_matScene + " : ");
            if (!Globals.doesNodeExists(w, as.lr_matScene)) {
              logLine("Building");
              NodeMod mod = Globals.registerNode(w, as.lr_matScene, "ma", Plugins.editorMaya(w));
              addedNodes.add(as.lr_matScene);
              BaseAction act = Plugins.actionMayaReference(w);
              Globals.referenceNode(w, as.lr_matScene, baseAsset.lr_rigScene, act, REF, "rig");
              mod.setAction(act);
              doReqs(mod);
              client.modifyProperties(user, view, mod);
            } else logLine("Already Exists");

            log(as.lr_finalScene + " : ");
            if (!Globals.doesNodeExists(w, as.lr_finalScene)) {
              logLine("Building");
              NodeMod mod = Globals.registerNode(w, as.lr_finalScene, "ma", Plugins.editorMaya(w));
              addedNodes.add(as.lr_finalScene);
              BaseAction act = Plugins.actionMayaImport(w);
              Globals.referenceNode(w, as.lr_finalScene, as.lr_matScene, act, DEP, "mat");
              client.link(user, view, as.lr_finalScene, finalizeMel, DEP, LINKALL, null);
              act.setSingleParamValue("ModelMEL", finalizeMel);
              mod.setAction(act);
              doReqs(mod);
              client.modifyProperties(user, view, mod);
            } else logLine("Already Exists");

            try {
              client.submitJobs(user, view, as.finalScene, null);
              client.submitJobs(user, view, as.lr_finalScene, null);
            } catch (PipelineException ex) {
              ex.printStackTrace();
            }

          } catch (PipelineException ex) {
            try {
              Globals.releaseNodes(w, addedNodes);
            } catch (PipelineException e) {
              e.printStackTrace();
            }
            ex.printStackTrace();
            return;
          }
        }

      } catch (PipelineException e) {
        e.printStackTrace();
      }
    } else if (pass == 2) {
      for (String name : toAdd) {
        try {
          logLine(name);
          SonyAsset baseAsset = SonyConstants.stringToAsset(w, baseModel);
          AssetType baseType = baseAsset.assetType;
          SonyAsset as = new SonyAsset(project, name, baseType);
          Globals.disableAction(w, as.matScene);
          Globals.disableAction(w, as.lr_matScene);
        } catch (PipelineException e) {
          e.printStackTrace();
        }
      }

    } else if (pass == 3) {
      for (String name : toAdd) {
        try {
          logLine(name);
          SonyAsset baseAsset = SonyConstants.stringToAsset(w, baseModel);
          AssetType baseType = baseAsset.assetType;
          SonyAsset as = new SonyAsset(project, name, baseType);
          NodeID nodeID = new NodeID(user, view, as.finalScene);

          client.checkIn(
              nodeID,
              "Inital model tree built by the BuildDerivedModels tool.  Built off the "
                  + baseModel
                  + " model",
              VersionID.Level.Minor);

          nodeID = new NodeID(user, view, as.lr_finalScene);
          client.checkIn(
              nodeID,
              "Inital model tree built by the BuildDerivedModels tool.  Built off the "
                  + baseModel
                  + " model",
              VersionID.Level.Minor);
        } catch (PipelineException e) {
          e.printStackTrace();
        }
      }
    }
  }
  /**
   * Updates the asset references for a shot within Maya and then in pipeline.
   *
   * @param shotName The name of the shot being processed.
   * @param pRemoveRef The list of assets being dereferenced from the shot.
   * @param pReplaceRef The list of assets being referenced into the shot.
   * @param nameMap
   */
  private void editShotReferences(
      String shotName,
      NodeMod targetMod,
      TreeSet<String> pRemoveRef,
      TreeSet<String> pReplaceRef,
      TreeMap<String, String> nameMap)
      throws PipelineException {
    logLine("Editing shot: " + shotName);
    boolean anim = !shotName.matches(lgtPattern);

    /* writing the mel script */
    if (anim) {
      File script = null;
      try {
        script = File.createTempFile("UpdateAssetGUI.", ".mel", PackageInfo.sTempPath.toFile());
        FileCleaner.add(script);
      } // end try
      catch (IOException ex) {
        throw new PipelineException(
            "Unable to create the temporary MEL script used to collect "
                + "texture information from the Maya scene!");
      } // end catch

      try {
        PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(script)));

        for (String asset : pReplaceRef) {
          String nameSpace;
          if (asset.endsWith(lr))
            nameSpace = nameMap.get(getShortName(asset.substring(0, asset.length() - 3)));
          else {
            System.err.println("This should not be happening, a hi res asset in a lo-res node.");
            continue;
            // nameSpace = nameMap.get(getShortName(asset));
          }
          out.println("print (\"referencing file: $WORKING" + asset + ".ma\");");
          out.println(
              "file -reference -namespace \"" + nameSpace + "\" \"$WORKING" + asset + ".ma\";");
        } // end for

        for (String asset : pRemoveRef) {
          out.println("print (\"dereferencing file: $WORKING" + asset + ".ma\");");
          out.println("file -rr \"$WORKING" + asset + ".ma\";");
        } // end for

        out.println("// SAVE");
        out.println("file -save;");

        out.close();
      } // end try
      catch (IOException ex) {
        throw new PipelineException(
            "Unable to write the temporary MEL script(" + script + ") used add the references!");
      } // end catch

      NodeID targetID = new NodeID(w.user, w.view, shotName);
      // NodeStatus targetStat = mclient.status(targetID);

      /* run Maya to collect the information */
      try {

        Path targetPath = getNodePath(shotName);
        ArrayList<String> args = new ArrayList<String>();
        args.add("-batch");
        args.add("-script");
        args.add(script.getPath());
        args.add("-file");
        args.add(targetPath.toOsString());

        Path wdir = new Path(PackageInfo.sProdPath.toOsString() + targetID.getWorkingParent());

        TreeMap<String, String> env =
            mclient.getToolsetEnvironment(
                w.user, w.view, targetMod.getToolset(), PackageInfo.sOsType);

        Map<String, String> nenv = env;
        String midefs = env.get("PIPELINE_MI_SHADER_PATH");
        if (midefs != null) {
          nenv = new TreeMap<String, String>(env);
          Path dpath = new Path(new Path(wdir, midefs));
          nenv.put("MI_CUSTOM_SHADER_PATH", dpath.toOsString());
        }

        String command = "maya";
        if (PackageInfo.sOsType.equals(OsType.Windows)) command += ".exe";

        SubProcessLight proc =
            new SubProcessLight("UpdateAssetGUI", command, args, env, wdir.toFile());
        try {
          proc.start();
          proc.join();
          if (!proc.wasSuccessful()) {
            throw new PipelineException(
                "Did not correctly edit the reference due to a maya error.!\n\n"
                    + proc.getStdOut()
                    + "\n\n"
                    + proc.getStdErr());
          } // end if
        } // end try
        catch (InterruptedException ex) {
          throw new PipelineException(ex);
        } // end catch
      } // end try
      catch (Exception ex) {
        throw new PipelineException(ex);
      } // end catch
    }

    /*-edit the references in pipeline once they are done in the file-*/
    BaseAction targetAction = targetMod.getAction();
    for (String asset : pReplaceRef) {
      mclient.link(
          w.user, w.view, shotName, asset, LinkPolicy.Reference, LinkRelationship.All, null);
      if (anim) {
        /*Set the namespaces*/
        String nameSpace = nameMap.get(getShortName(asset.substring(0, asset.length() - 3)));
        System.err.println(nameSpace);
        targetAction.initSourceParams(asset);
        targetAction.setSourceParamValue(asset, "PrefixName", nameSpace);
        targetMod.setAction(targetAction);
      }
    }
    w.mclient.modifyProperties(w.user, w.view, targetMod);

    for (String asset : pRemoveRef) mclient.unlink(w.user, w.view, shotName, asset);

    if (!anim) {
      System.err.println("Queuing the switchLgt node " + shotName);
      mclient.submitJobs(w.user, w.view, shotName, null);
    }
  } // end editShotReferences
  private boolean dylanate(
      MasterMgrClient mclient,
      String switchName,
      DoubleMap<String, String, TreeSet<VersionID>> plugs)
      throws PipelineException {
    err.println("\nProcessing: " + switchName);
    String animName = null;

    {
      NodeMod switchMod = null;
      try {
        switchMod = mclient.getWorkingVersion(pUser, pView, switchName);
      } catch (PipelineException e) {
        mclient.checkOut(pUser, pView, switchName, null, keep, pFroz);
        switchMod = mclient.getWorkingVersion(pUser, pView, switchName);
      }

      TreeSet<String> switchSrcs = new TreeSet<String>(switchMod.getSourceNames());

      for (String src : switchSrcs) {
        if (src.matches(animPattern)) {
          animName = src;
          err.println("Found anim node: " + src);
          mclient.checkOut(pUser, pView, src, null, over, frozU);
          continue;
        } // end if

        mclient.checkOut(pUser, pView, src, null, over, frozU);

        LinkMod lMod = switchMod.getSource(src);
        LinkPolicy rel = lMod.getPolicy();
        System.err.println(src + ": " + rel);
        if (!rel.equals(REF)) {
          System.err.println("umm");
          lMod.setPolicy(REF);
          switchMod.setSource(lMod);
          mclient.modifyProperties(pUser, pView, switchMod);
        }
      } // end for

      err.println("anim node: " + animName);

      mclient.modifyProperties(pUser, pView, switchMod);

      if (animName == null)
        throw new PipelineException("This switch node does not have an associated anim node");
    }
    err.println("Checked out the anim and switch nodes");

    String actionName = null;
    VersionID ttVer = null;
    boolean toCache = false;

    /*change the action setting on the Switch node*/
    {
      NodeMod switchMod = mclient.getWorkingVersion(pUser, pView, switchName);

      Path p = new Path(switchName);
      Path syfRoot = new Path(p.getParentPath().getParentPath(), "syf");
      System.err.println("Going to look for caches in: " + syfRoot);
      ArrayList<String> syfDirs = getChildrenDirs(mclient, syfRoot.toString());

      for (String dir : syfDirs) {
        System.err.println(dir);
        Path dPath = new Path(syfRoot, dir);
        ArrayList<String> simDir = getChildrenNodes(mclient, dPath.toString());
        for (String pCache : simDir) {
          Path cPath = new Path(dPath, pCache);
          if (cPath.toString().matches(cltPattern)) {
            System.err.println("\t" + cPath.toString());
            try {
              mclient.checkOut(pUser, pView, cPath.toString(), null, over, froz);
              mclient.lock(pUser, pView, cPath.toString(), null);
              mclient.link(pUser, pView, switchMod.getName(), cPath.toString(), DEP, LINKALL, null);
            } catch (PipelineException e) {
              e.printStackTrace();
            }
            toCache = true;
          }
        }
      }

      {
        BaseAction action = switchMod.getAction();
        if (!switchMod.getToolset().equals(pToolset)) {
          switchMod.setToolset(pToolset);
          mclient.modifyProperties(pUser, pView, switchMod);
        }

        if (!toCache) {
          actionName = modRep;
        } else {
          actionName = modRep + "Syflex";
        }
        ttVer = plugs.get("SCEA", actionName).last();

        if ((action == null)
            || (!action.getName().equals(actionName))
            || (!action.getVersionID().equals(ttVer))) {
          System.err.println(
              "Action name is incorrect - the switch node "
                  + switchName
                  + " doesn't have a "
                  + actionName
                  + "Action");

          action = plug.newAction(actionName, ttVer, "SCEA");
          action.setSingleParamValue("Source", animName);
          action.setSingleParamValue("Response", "Ignore");
          if (toCache) action.setSingleParamValue(aApplyCache, true);
          switchMod.setAction(action);
          mclient.modifyProperties(pUser, pView, switchMod);
        } else {
          if (!action.getSingleParamValue("Response").equals("Ignore")) {
            //						action = plug.newAction(actionName, ttVer, "SCEA");
            //						action.setSingleParamValue("Source", animName);
            action.setSingleParamValue("Response", "Ignore");
            //						if(toCache)
            //						action.setSingleParamValue(aApplyCache, true);
            switchMod.setAction(action);
            mclient.modifyProperties(pUser, pView, switchMod);
          } // end if
        } // end else
      }
    }

    {
      /*-check out and lock the animation sources-*/
      NodeMod animMod = mclient.getWorkingVersion(pUser, pView, animName);
      Set<String> animSrcs = animMod.getSourceNames();
      for (String src : animSrcs) {
        if (src.matches(loresPattern)) {
          pLoresSrcs.add(src);
          err.println("Adding lores src " + src);
        }
        mclient.checkOut(pUser, pView, src, null, keep, pFroz);
      } // end for
      err.println("lores:" + pLoresSrcs);
    }

    /*-sync the animation assets with the switch assets.*/
    // also remove unnecessary hires models
    {
      NodeMod switchMod = mclient.getWorkingVersion(pUser, pView, switchName);
      for (String src : switchMod.getSourceNames()) {
        if (src.matches(hiresPattern)) {
          err.println("Found hires source " + src);
          if (pLoresSrcs.contains(src + "_lr")) {
            pHiresSrcs.add(src);
            err.println("The hires source matched the anim node.");
          } else {
            err.println("Gotta remove " + src);
          } // end else
        } // end if
      } // end for
    }

    // add necessary hires models
    for (String lores : pLoresSrcs) {
      String hr = lores.replace("_lr", "");
      err.println("Looking at lores source " + lores + " which matches " + hr);
      if (!pHiresSrcs.contains(hr)) {
        err.println("Gotta add " + hr + " to " + switchName);
        pHiresSrcs.add(hr);
      }
    }

    {
      NodeMod switchMod = mclient.getWorkingVersion(pUser, pView, switchName);
      TreeSet<String> switchSrcs = new TreeSet<String>(switchMod.getSourceNames());
      err.println("Final hiRes list:" + pHiresSrcs + "\n");
      err.println("switch now has:\n\t" + switchSrcs + "\n");
      err.println("Looking for things to add.");
      for (String src : pHiresSrcs) {
        if ((src.matches(hiresPattern) && (!switchSrcs.contains(src)))) {
          err.print("Linking ");
          mclient.checkOut(pUser, pView, src, null, over, frozU);
          mclient.link(pUser, pView, pPrimary, src, REF, LINKALL, null);
          switchSrcs.add(src);
        }
        err.println("src from hiRes list: " + src);
      }
    }

    {
      NodeMod switchMod = mclient.getWorkingVersion(pUser, pView, switchName);
      TreeSet<String> switchSrcs = new TreeSet<String>(switchMod.getSourceNames());
      err.println("switch now has:\n\t" + switchSrcs + "\n");
      for (String src : switchSrcs) {
        if ((src.matches(hiresPattern) && (!pHiresSrcs.contains(src)))) {
          err.print("Unlinking ");
          mclient.unlink(pUser, pView, pPrimary, src);
        }
        err.println("src from switch node list: " + src);
      }
    }

    /*queue the switch node*/
    mclient.submitJobs(pUser, pView, switchName, null);

    return false;
  }