/*
 * Copyright 2012 Red Hat, Inc. and/or its affiliates.
 *
 * Licensed under the Eclipse Public License Version 1.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.eclipse.org/legal/epl-v10.html
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.jboss.undo.forge;

import javax.enterprise.event.Event;
import javax.inject.Inject;

import org.jboss.forge.env.Configuration;
import org.jboss.forge.jgit.revwalk.RevCommit;
import org.jboss.forge.parser.java.util.Strings;
import org.jboss.forge.project.Project;
import org.jboss.forge.project.facets.events.InstallFacets;
import org.jboss.forge.shell.ShellMessages;
import org.jboss.forge.shell.plugins.Alias;
import org.jboss.forge.shell.plugins.Command;
import org.jboss.forge.shell.plugins.Help;
import org.jboss.forge.shell.plugins.Option;
import org.jboss.forge.shell.plugins.PipeOut;
import org.jboss.forge.shell.plugins.Plugin;
import org.jboss.forge.shell.plugins.RequiresFacet;
import org.jboss.forge.shell.plugins.RequiresProject;
import org.jboss.forge.shell.plugins.SetupCommand;

/**
 * @author <a href="mailto:jevgeni.zelenkov@gmail.com">Jevgeni Zelenkov</a>
 *
 */
@Alias("undo")
@Help("Provides a possibility to revert changes introduced by the forge commands")
@RequiresFacet(UndoFacet.class)
@RequiresProject
public class UndoPlugin implements Plugin
{
   private static final int GIT_HASH_ABBREV_SIZE = 7;

   @Inject
   private Configuration config;

   @Inject
   private Project project;

   @Inject
   private Event<InstallFacets> install;

   @SetupCommand()
   public void setup(@Option(name = "branchName") String branchName,
            PipeOut out)
   {
      if (Strings.isNullOrEmpty(branchName))
         config.addProperty(UndoFacet.HISTORY_BRANCH_CONFIG_KEY, UndoFacet.DEFAULT_HISTORY_BRANCH_NAME);
      else
         config.addProperty(UndoFacet.HISTORY_BRANCH_CONFIG_KEY, branchName);

      if (!project.hasFacet(UndoFacet.class))
         install.fire(new InstallFacets(UndoFacet.class));

      if (project.hasFacet(UndoFacet.class))
         ShellMessages.success(out, "Undo plugin is installed.");
   }

   @Command(value = "list", help = "list changes stored in the undo branch")
   public void listCommand(PipeOut out) throws Exception
   {
      Iterable<RevCommit> commits = project.getFacet(UndoFacet.class).getStoredCommitsOnHistoryBranch();

      for (RevCommit commit : commits)
         out.println(commit.getId().abbreviate(GIT_HASH_ABBREV_SIZE).name() + " " + commit.getShortMessage());
   }

   @Command(value = "restore", help = "reverts the changes introduced by the last forge command")
   public void undoCommand(PipeOut out) throws Exception
   {
      boolean isReverted = project.getFacet(UndoFacet.class).undoLastChange();

      if (isReverted)
         ShellMessages.success(out, "latest forge command is reverted.");
      else
         ShellMessages.info(out, "nothing happened.");
   }

   @Command(value = "reset", help = "remove all stored changesets in the history branch. It's only possible to reset undo branch from the clean state.")
   public void resetCommand(PipeOut out) throws Exception
   {
      boolean isReset = project.getFacet(UndoFacet.class).reset();

      if (isReset)
         ShellMessages.success(out, "history branch was reset successfully.");
      else
         ShellMessages.info(out, "Nothing happened. History branch is either empty already or your git repository is not in clean state.");
   }

}

@@ -651,16 +651,67 @@
 forge;%0A%0A
+import java.util.Map;%0Aimport java.util.Map.Entry;%0A%0A
 import j
@@ -2678,16 +2678,11 @@
     
-Iterable
+Map
 %3CRev
@@ -2687,16 +2687,24 @@
 evCommit
+, String
 %3E commit
@@ -2704,16 +2704,25 @@
  commits
+WithNotes
  = proje
@@ -2766,16 +2766,25 @@
 dCommits
+WithNotes
 OnHistor
@@ -2806,16 +2806,22 @@
    for (
+Entry%3C
 RevCommi
@@ -2825,48 +2825,305 @@
 mmit
- commit : commits)%0A         out.println(
+, String %3E each : commitsWithNotes.entrySet())%0A      %7B%0A         RevCommit commit = each.getKey();%0A         String note = (each.getValue() != null) ? each.getValue() : %22*NULL*%22;%0A         if(Strings.areEqual(note, UndoFacet.DEFAULT_NOTE))%0A            note = %22*uncommitted*%22;%0A%0A         String line = 
 comm
@@ -3176,16 +3176,31 @@
 me() + %22
+ %5B%22 + note + %22%5D
  %22 + com
@@ -3220,18 +3220,53 @@
 essage()
-)
 ;
+%0A         out.println(line);%0A      %7D
 %0A   %7D%0A%0A 

Undo list shows to which branch changesets belong to