/*******************************************************************************
 * Copyright (c) 2011 Boeing.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Boeing - initial API and implementation
 *******************************************************************************/
package org.eclipse.osee.ats.ide.workflow.transition;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.nebula.widgets.xviewer.XViewer;
import org.eclipse.osee.ats.api.AtsApi;
import org.eclipse.osee.ats.api.IAtsWorkItem;
import org.eclipse.osee.ats.api.user.AtsUser;
import org.eclipse.osee.ats.api.util.IAtsChangeSet;
import org.eclipse.osee.ats.api.workdef.IAtsLayoutItem;
import org.eclipse.osee.ats.api.workdef.IAtsStateDefinition;
import org.eclipse.osee.ats.api.workflow.hooks.IAtsTransitionHook;
import org.eclipse.osee.ats.api.workflow.transition.ITransitionHelper;
import org.eclipse.osee.ats.api.workflow.transition.TransitionData;
import org.eclipse.osee.ats.api.workflow.transition.TransitionResults;
import org.eclipse.osee.ats.core.workflow.state.TeamState;
import org.eclipse.osee.ats.core.workflow.transition.TransitionHelperAdapter;
import org.eclipse.osee.ats.ide.AtsImage;
import org.eclipse.osee.ats.ide.internal.Activator;
import org.eclipse.osee.ats.ide.internal.AtsClientService;
import org.eclipse.osee.ats.ide.util.AtsUtilClient;
import org.eclipse.osee.ats.ide.workflow.AbstractWorkflowArtifact;
import org.eclipse.osee.framework.core.operation.Operations;
import org.eclipse.osee.framework.jdk.core.type.OseeCoreException;
import org.eclipse.osee.framework.logging.OseeLevel;
import org.eclipse.osee.framework.logging.OseeLog;
import org.eclipse.osee.framework.ui.plugin.util.AWorkbench;
import org.eclipse.osee.framework.ui.plugin.util.AWorkbench.MessageType;
import org.eclipse.osee.framework.ui.skynet.widgets.dialog.EntryCancelWidgetDialog;
import org.eclipse.osee.framework.ui.skynet.widgets.dialog.EntryDialog;
import org.eclipse.osee.framework.ui.swt.Displays;
import org.eclipse.osee.framework.ui.swt.ImageManager;
import org.eclipse.swt.widgets.TreeItem;

/**
 * @author Donald G. Dunne
 */
public class TransitionToMenu {
   public static MenuManager createTransitionToMenuManager(final XViewer xViewer, String name, final Collection<TreeItem> selectedTreeItems) {
      MenuManager editMenuManager =
         new MenuManager(name, ImageManager.getImageDescriptor(AtsImage.TRANSITION), "transition-to");
      final Set<IAtsWorkItem> workItems = new HashSet<>();
      Set<IAtsStateDefinition> toStateDefs = new HashSet<>();
      String workDefinitionId = null;
      Map<String, IAtsStateDefinition> stateNameToStateDef = new HashMap<>();
      boolean multipleWorkDefinitions = false;
      for (TreeItem treeItem : selectedTreeItems) {
         if (treeItem.getData() instanceof AbstractWorkflowArtifact) {
            AbstractWorkflowArtifact awa = (AbstractWorkflowArtifact) treeItem.getData();
            workItems.add(awa);
            if (!multipleWorkDefinitions) {
               if (workDefinitionId == null) {
                  workDefinitionId = awa.getWorkDefinition().getName();
               } else if (!workDefinitionId.equals(awa.getWorkDefinition().getName())) {
                  multipleWorkDefinitions = true;
               }
            }
            try {
               for (IAtsStateDefinition stateDef : awa.getToStatesWithCompleteCancelReturnStates()) {
                  toStateDefs.add(stateDef);
                  stateNameToStateDef.put(stateDef.getName(), stateDef);
               }
            } catch (OseeCoreException ex) {
               OseeLog.log(Activator.class, Level.SEVERE, ex);
            }
         }
      }
      if (toStateDefs.isEmpty()) {
         editMenuManager.add(
            new Action("No Transitionable Selections", ImageManager.getImageDescriptor(AtsImage.TRANSITION)) {

               @Override
               public void run() {
                  AWorkbench.popup("Error", "No selection is in a transitionable state or transitionable together.");
               }

            });
      } else {
         List<String> toStateNames = new ArrayList<>();
         if (multipleWorkDefinitions) {
            for (IAtsStateDefinition stateDef : toStateDefs) {
               if (!toStateNames.contains(stateDef.getName())) {
                  toStateNames.add(stateDef.getName());
               }
            }
            Collections.sort(toStateNames);
         } else {
            Set<Integer> stateOrdinals = new HashSet<>();
            for (final IAtsStateDefinition stateDef : toStateDefs) {
               stateOrdinals.add(stateDef.getOrdinal());
            }
            Integer[] toStates = stateOrdinals.toArray(new Integer[stateOrdinals.size()]);
            Arrays.sort(toStates);
            for (Integer stateOrdinal : stateOrdinals) {
               for (final IAtsStateDefinition stateDef : toStateDefs) {
                  if (stateDef.getOrdinal() == stateOrdinal) {
                     toStateNames.add(stateDef.getName());
                  }
               }
            }
         }
         for (String stateName : toStateNames) {
            editMenuManager.add(
               new Action(getTransitionToString(stateName, multipleWorkDefinitions, stateNameToStateDef),
                  ImageManager.getImageDescriptor(AtsImage.TRANSITION)) {

                  @Override
                  public void run() {
                     handleTransitionToSelected(stateName, workItems);
                  }

               });
         }
      }
      return editMenuManager;
   }

   private static String getTransitionToString(String stateDefName, boolean multipleWorkDefinitions, Map<String, IAtsStateDefinition> stateNameToStateDef) {
      if (multipleWorkDefinitions) {
         return stateDefName;
      } else {
         IAtsStateDefinition stateDef = stateNameToStateDef.get(stateDefName);
         return String.format("%s%s%s", stateDef.getName(), getStateTypeName(stateDef),
            getDefaultStatePercent(stateDef));
      }
   }

   private static Object getDefaultStatePercent(IAtsStateDefinition stateDef) {
      if (stateDef.getRecommendedPercentComplete() != null && stateDef.getRecommendedPercentComplete() != 0) {
         return String.format(" - %d%%", stateDef.getRecommendedPercentComplete());
      }
      return "";
   }

   private static String getStateTypeName(IAtsStateDefinition stateDef) {
      return stateDef.getStateType().isWorkingState() || stateDef.getName().equals(
         TeamState.Completed.getName()) || stateDef.getName().equals(
            TeamState.Cancelled.getName()) ? "" : " (" + stateDef.getStateType().name() + ")";
   }

   private static void handleTransitionToSelected(final String toStateName, final Set<IAtsWorkItem> workItems) {
      final ITransitionHelper helper = new TransitionHelperAdapter(AtsClientService.get().getServices()) {

         @Override
         public String getToStateName() {
            return toStateName;
         }

         @Override
         public Collection<AtsUser> getToAssignees(IAtsWorkItem workItem) {
            return workItem.getAssignees();
         }

         @Override
         public String getName() {
            return "Transition-To " + getToStateName();
         }

         @Override
         public TransitionData getCancellationReason(TransitionData transitionData) {
            Displays.ensureInDisplayThread(new Runnable() {

               @Override
               public void run() {
                  IAtsWorkItem workItem = getWorkItems().iterator().next();
                  IAtsStateDefinition stateDef = null;
                  try {
                     stateDef = AtsClientService.get().getWorkDefinitionService().getStateDefinitionByName(workItem,
                        getToStateName());
                  } catch (OseeCoreException ex) {
                     OseeLog.log(Activator.class, OseeLevel.SEVERE_POPUP, ex);
                  }
                  if (stateDef != null && stateDef.getStateType().isCancelledState()) {
                     EntryDialog cancelDialog;
                     boolean useEntryCancelWidgetDialog = false;
                     for (IAtsLayoutItem layoutItem : stateDef.getLayoutItems()) {
                        if (layoutItem.getName().contains("Cancel")) {
                           useEntryCancelWidgetDialog = true;
                           break;
                        }
                     }
                     if (useEntryCancelWidgetDialog) {
                        cancelDialog = new EntryCancelWidgetDialog("Cancellation Reason",
                           "Select cancellation reason.  If other, please specify with details in the text entry.");
                     } else {
                        cancelDialog = new EntryDialog("Cancellation Reason", "Enter cancellation reason.");
                     }
                     if (cancelDialog.open() != 0) {
                        transitionData.setDialogCancelled(true);
                     }
                     if (useEntryCancelWidgetDialog) {
                        transitionData.setCancellationReason(((EntryCancelWidgetDialog) cancelDialog).getEntry());
                        transitionData.setCancellationReasonDetails(
                           ((EntryCancelWidgetDialog) cancelDialog).getCancelledDetails());
                     } else {
                        transitionData.setCancellationReason(cancelDialog.getEntry());
                     }
                  }
               }

            }, true);
            return transitionData;
         }

         @Override
         public Collection<IAtsWorkItem> getWorkItems() {
            return workItems;
         }

         @Override
         public IAtsChangeSet getChangeSet() {
            return null;
         }

         @Override
         public Collection<IAtsTransitionHook> getTransitionListeners() {
            try {
               Set<IAtsTransitionHook> listeners = new HashSet<>();
               listeners.addAll(AtsClientService.get().getWorkItemService().getTransitionHooks());
            } catch (OseeCoreException ex) {
               OseeLog.log(Activator.class, Level.SEVERE, ex);
            }
            return java.util.Collections.emptyList();
         }

         @Override
         public AtsApi getServices() {
            return AtsClientService.get().getServices();
         }

         @Override
         public String getCancellationReasonDetails() {
            return null;
         }

         @Override
         public String getCancellationReason() {
            return null;
         }

      };
      final TransitionToOperation operation = new TransitionToOperation(helper);
      Operations.executeAsJob(operation, true, Job.SHORT, new JobChangeAdapter() {

         @Override
         public void done(IJobChangeEvent event) {
            TransitionResults results = operation.getResults();
            if (results.isErrors()) {
               AtsUtilClient.logExceptions(results);
               if (helper.getWorkItems().size() == 1) {
                  String resultStr = results.getResultString();
                  AWorkbench.popup(MessageType.Error, "Transition Failed", resultStr);
               } else {
                  TransitionResultsUi.reportDialog("Transition Failed", results);
               }
            }
         }

      });
   }

}
