/** {@inheritDoc} */
  @Override
  public ActionForward execute(
      ActionMapping mapping,
      ActionForm formIn,
      HttpServletRequest request,
      HttpServletResponse response) {

    RequestContext requestContext = new RequestContext(request);
    Server server = requestContext.lookupAndBindServer();
    Long aid = requestContext.getRequiredParam("aid");

    request.setAttribute("aid", aid);
    request.setAttribute("referrerLink", "History.do");
    request.setAttribute("linkLabel", "system.event.return");
    request.setAttribute("headerLabel", "system.event.header");

    Action action;
    ServerAction serverAction;
    try {
      action = ActionManager.lookupAction(requestContext.getCurrentUser(), aid);
      serverAction = ActionFactory.getServerActionForServerAndAction(server, action);
    } catch (LookupException e) {
      ServerHistoryEvent event = ActionFactory.lookupHistoryEventById(aid);
      request.setAttribute("actiontype", event.getSummary());
      request.setAttribute("earliestaction", event.getCreated());
      request.setAttribute("actionnotes", event.getDetails());
      request.setAttribute("failed", false);
      return mapping.findForward(RhnHelper.DEFAULT_FORWARD);
    }
    ActionFormatter af = action.getFormatter();
    request.setAttribute("actionname", af.getName());
    request.setAttribute("actiontype", af.getActionType());
    request.setAttribute("scheduler", af.getScheduler());
    request.setAttribute("earliestaction", af.getEarliestDate());
    request.setAttribute("actionnotes", af.getDetails(server, requestContext.getCurrentUser()));
    request.setAttribute("failed", serverAction.getStatus().equals(ActionFactory.STATUS_FAILED));
    if (!serverAction.getStatus().equals(ActionFactory.STATUS_COMPLETED)
        && !serverAction.getStatus().equals(ActionFactory.STATUS_FAILED)) {
      request.setAttribute("referrerLink", "Pending.do");
      request.setAttribute("linkLabel", "system.event.pendingReturn");
      request.setAttribute("headerLabel", "system.event.pendingHeader");
    }
    if (isSubmitted((DynaActionForm) formIn)) {
      createSuccessMessage(request, "system.event.rescheduled", action.getName());
      ActionFactory.rescheduleSingleServerAction(action, 5L, server.getId());
      return mapping.findForward("continue");
    }

    return mapping.findForward(RhnHelper.DEFAULT_FORWARD);
  }
  /**
   * Test fetching a PackageAction
   *
   * @throws Exception
   */
  public void testLookupPackageAction() throws Exception {

    Action newA =
        ActionFactoryTest.createAction(
            UserTestUtils.createUser(
                "testUser", UserTestUtils.createOrg("testOrg" + this.getClass().getSimpleName())),
            ActionFactory.TYPE_PACKAGES_VERIFY);
    assertNotNull(newA.getId());
    assertTrue(newA instanceof PackageAction);
    PackageAction p = (PackageAction) newA;
    assertNotNull(p.getDetails());
    assertEquals(p.getDetails().size(), 1);
    PackageActionDetails firstDetail = (PackageActionDetails) p.getDetails().toArray()[0];

    /** Make sure PackageEvr was set & committed correctly */
    Set details = p.getDetails();
    Iterator ditr = details.iterator();
    while (ditr.hasNext()) {
      PackageActionDetails detail = (PackageActionDetails) ditr.next();
      assertNotNull(detail.getEvr().getId());
    }

    User user = UserTestUtils.findNewUser("TEST USER", "TEST ORG");
    Server testserver = ServerFactoryTest.createTestServer(user);

    PackageActionResult result = new PackageActionResult();
    result.setServer(testserver);
    result.setDetails(firstDetail);
    result.setResultCode(new Long(42));
    result.setCreated(new Date());
    result.setModified(new Date());

    firstDetail.addResult(result);

    ActionFactory.save(p);

    PackageAction p2 = (PackageAction) ActionFactory.lookupById(p.getId());

    assertNotNull(p2.getDetails());
    assertEquals(p2.getDetails().size(), 1);
    assertNotNull(p2.getDetails().toArray()[0]);
    firstDetail = (PackageActionDetails) p2.getDetails().toArray()[0];
    assertNotNull(firstDetail.getResults());
    assertEquals(firstDetail.getResults().size(), 1);
  }
  private void showMessages(
      ActionMessages msgs, Action action, Server server, int pkgcnt, String mode) {
    String key = null;

    if (MODE_INSTALL.equals(mode)) {
      key = "message.packageinstall";
    } else if (MODE_REMOVAL.equals(mode)) {
      key = "message.packageremoval";
    } else { // must be upgrade
      key = "message.packageupgrade";
    }

    /**
     * If there was only one action archived, display the "action" archived message, else display
     * the "actions" archived message.
     */
    if (pkgcnt == 1) {
      msgs.add(
          ActionMessages.GLOBAL_MESSAGE,
          new ActionMessage(
              key,
              LocalizationService.getInstance().formatNumber(new Integer(pkgcnt)),
              action.getId().toString(),
              server.getId().toString(),
              server.getName()));
    } else {
      msgs.add(
          ActionMessages.GLOBAL_MESSAGE,
          new ActionMessage(
              key + "s",
              LocalizationService.getInstance().formatNumber(new Integer(pkgcnt)),
              action.getId().toString(),
              server.getId().toString(),
              server.getName()));
    }
  }
  /**
   * @param prereqAction the prerequisite for this action
   * @return Returns the rebootAction (if any)
   */
  public Action scheduleRebootAction(Action prereqAction) {

    // All actions must be scheduled against the host server.

    Action rebootAction =
        ActionManager.scheduleRebootAction(
            this.getUser(), this.getHostServer(), this.getScheduleDate());
    log.debug("** Created rebootAction");
    rebootAction.setPrerequisite(prereqAction);
    rebootAction.setEarliestAction(this.getScheduleDate());
    rebootAction.setOrg(this.getUser().getOrg());
    rebootAction.setName(rebootAction.getActionType().getName());
    log.debug("** saving reboot action: " + rebootAction.getName());
    ActionFactory.save(rebootAction);
    log.debug("** Saved rebootAction: " + rebootAction.getId());

    return rebootAction;
  }
  /** {@inheritDoc} */
  public ValidatorError store() {

    ValidatorError e = this.doValidation();
    if (e != null) {
      return e;
    }

    Server hostServer = getHostServer();
    log.debug("** Server we are operating on: " + hostServer);

    // rhn-kickstart-virtualization conflicts with this package, so we have to
    //  remove it
    List<Map<String, Long>> installed =
        SystemManager.listInstalledPackage(PACKAGE_TO_REMOVE, hostServer);
    Action removal = null;
    if (!installed.isEmpty()) {
      removal = ActionManager.schedulePackageRemoval(user, hostServer, installed, scheduleDate);
    }

    // Install packages on the host server.
    log.debug("** Creating packageAction");
    Action packageAction =
        ActionManager.schedulePackageInstall(
            this.user, hostServer, this.packagesToInstall, scheduleDate);
    packageAction.setPrerequisite(removal);
    log.debug("** Created packageAction ? " + packageAction.getId());

    log.debug("** Cancelling existing sessions.");
    cancelExistingSessions();

    // Make sure we fail all existing sessions for this server since
    // we are scheduling a new one
    if (!cobblerOnly) {
      kickstartSession = this.setupKickstartSession(packageAction);
      storeActivationKeyInfo();
    }
    Action kickstartAction = this.scheduleKickstartAction(packageAction);
    ActionFactory.save(packageAction);

    scheduleRebootAction(kickstartAction);

    String host = this.getKickstartServerName();
    if (!StringUtils.isEmpty(this.getProxyHost())) {
      host = this.getProxyHost();
    }

    CobblerSystemCreateCommand cmd = null;
    if (!cobblerOnly) {
      // Setup Cobbler system profile
      KickstartUrlHelper uhelper = new KickstartUrlHelper(ksdata);
      String tokenList;

      if (ksdata.getRegistrationType(null).equals(RegistrationType.REACTIVATION)) {
        tokenList = KickstartFormatter.generateActivationKeyString(ksdata, kickstartSession);
      } else {
        // RegistrationType.DELETION && RegistrationType.NONE
        CobblerConnection connection =
            CobblerXMLRPCHelper.getConnection(ConfigDefaults.get().getCobblerAutomatedUser());
        tokenList =
            org.cobbler.Profile.lookupById(connection, ksdata.getCobblerId())
                .getRedHatManagementKey();
      }

      cmd =
          getCobblerSystemCreateCommand(
              user,
              server,
              ksdata,
              uhelper.getKickstartMediaPath(kickstartSession, scheduleDate),
              tokenList);
      cmd.setKernelOptions(getExtraOptions());
    } else {
      cmd = new CobblerSystemCreateCommand(user, server, cobblerProfileLabel);
      cmd.setKernelOptions(kernelOptions);
    }
    cmd.setKickstartHost(host);
    cmd.setPostKernelOptions(postKernelOptions);
    cmd.setScheduledAction(kickstartAction);
    cmd.setNetworkInfo(
        isDhcp, networkInterface, this.useIpv6Gateway(), ksdata.getInstallType().getLabel());
    cmd.setBridgeInfo(
        createBond,
        bondInterface,
        bondSlaveInterfaces,
        bondOptions,
        isBondDhcp,
        bondAddress,
        bondNetmask,
        bondGateway);
    ValidatorError cobblerError = cmd.store();
    if (cobblerError != null) {
      return cobblerError;
    }
    SystemRecord rec =
        SystemRecord.lookupById(
            CobblerXMLRPCHelper.getConnection(this.getUser().getLogin()),
            this.getServer().getCobblerId());

    // This is a really really crappy way of doing this, but i don't want to restructure
    //      the actions too much at this point :/
    //      We only want to do this for the non-guest action
    if (kickstartAction instanceof KickstartAction) {
      ((KickstartAction) kickstartAction)
          .getKickstartActionDetails()
          .setCobblerSystemName(rec.getName());
    }

    ActionFactory.save(kickstartAction);
    log.debug("** Created ksaction: " + kickstartAction.getId());

    this.scheduledAction = kickstartAction;

    log.debug("** Done scheduling kickstart session");
    return null;
  }
  /**
   * Tests save().
   *
   * @throws Exception if something bad happens
   */
  @SuppressWarnings("unchecked")
  public void testSave() throws Exception {
    RhnMockHttpServletRequest request = TestUtils.getRequestWithSessionAndUser();
    user = new RequestContext(request).getCurrentUser();

    ActionChainSaveAction saveAction = new ActionChainSaveAction();
    String label = TestUtils.randomString();
    ActionChain actionChain = ActionChainFactory.createActionChain(label, user);
    for (int i = 0; i < 6; i++) {
      Action action = ActionFactory.createAction(ActionFactory.TYPE_ERRATA);
      action.setOrg(user.getOrg());
      ActionFactory.save(action);
      ActionChainFactory.queueActionChainEntry(
          action, actionChain, ServerFactoryTest.createTestServer(user), i / 2);
    }
    Action lastAction = ActionFactory.createAction(ActionFactory.TYPE_ERRATA);
    lastAction.setOrg(user.getOrg());
    ActionFactory.save(lastAction);
    ActionChainFactory.queueActionChainEntry(
        lastAction, actionChain, ServerFactoryTest.createTestServer(user), 3);

    String newLabel = TestUtils.randomString();
    List<Long> deletedEntries = new LinkedList<Long>();
    deletedEntries.add(lastAction.getId());
    List<Integer> deletedSortOrders = new LinkedList<Integer>();
    deletedSortOrders.add(0);
    deletedSortOrders.add(3);
    List<Integer> reorderedSortOrders = new LinkedList<Integer>();
    reorderedSortOrders.add(2);
    reorderedSortOrders.add(1);

    String resultString =
        saveAction.save(
            actionChain.getId(),
            newLabel,
            deletedEntries,
            deletedSortOrders,
            reorderedSortOrders,
            request);

    Map<String, Object> result = (Map<String, Object>) new JSONReader().read(resultString);
    assertEquals(true, result.get(ActionChainSaveAction.SUCCESS_FIELD));
    assertEquals(
        LocalizationService.getInstance().getMessage("actionchain.jsp.saved"),
        result.get(ActionChainSaveAction.TEXT_FIELD));
    assertEquals(newLabel, actionChain.getLabel());

    Set<ActionChainEntry> entries = actionChain.getEntries();
    assertEquals(4, entries.size());

    List<ActionChainEntry> sortedEntries = new LinkedList<ActionChainEntry>();
    sortedEntries.addAll(entries);
    Collections.sort(
        sortedEntries,
        new Comparator<ActionChainEntry>() {
          public int compare(ActionChainEntry entry1, ActionChainEntry entry2) {
            return entry1.getId().compareTo(entry2.getId());
          }
        });
    for (int i = 0; i < sortedEntries.size(); i++) {
      assertEquals((Integer) (1 - i / 2), sortedEntries.get(i).getSortOrder());
    }
  }