package org.yamcs.studio.commanding.stack;

import java.io.UnsupportedEncodingException;
import java.util.logging.Logger;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.handlers.HandlerUtil;
import org.yamcs.protobuf.IssueCommandRequest;
import org.yamcs.protobuf.Mdb.SignificanceInfo;
import org.yamcs.studio.commanding.stack.StackedCommand.StackedState;
import org.yamcs.studio.core.model.CommandingCatalogue;

public class ArmCommandHandler extends AbstractHandler {

    private static final Logger log = Logger.getLogger(ArmCommandHandler.class.getName());

    @Override
    public Object execute(ExecutionEvent event) throws ExecutionException {
        IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindowChecked(event);
        IWorkbenchPart part = window.getActivePage().findView(CommandStackView.ID);
        CommandStackView commandStackView = (CommandStackView) part;

        Shell shell = HandlerUtil.getActiveShellChecked(event);
        CommandStack stack = CommandStack.getInstance();
        StackedCommand command = stack.getActiveCommand();
        armCommand(shell, commandStackView, command);

        return null;
    }

    private void armCommand(Shell activeShell, CommandStackView view, StackedCommand command)
            throws ExecutionException {
        IssueCommandRequest req = command.toIssueCommandRequest().setDryRun(true).build();

        CommandingCatalogue catalogue = CommandingCatalogue.getInstance();
        String qname;
        try {
            qname = command.getSelectedAliasEncoded();
        } catch (UnsupportedEncodingException e1) {
            throw new ExecutionException(e1.getMessage());
        }

        catalogue.sendCommand("realtime", qname, req).whenComplete((data, exc) -> {
            if (exc == null) {
                Display.getDefault().asyncExec(() -> {
                    boolean doArm = false;
                    SignificanceInfo significance = command.getMetaCommand().getSignificance();
                    switch (significance.getConsequenceLevel()) {
                    case WATCH:
                    case WARNING:
                    case DISTRESS:
                    case CRITICAL:
                    case SEVERE:
                        String level = Character.toUpperCase(significance.getConsequenceLevel().toString().charAt(0))
                                + significance.getConsequenceLevel().toString().substring(1);
                        if (MessageDialog.openConfirm(activeShell, "Confirm",
                                level + ": Are you sure you want to arm this command?\n" +
                                        "    " + command.toStyledString(view).getString() + "\n\n" +
                                        significance.getReasonForWarning())) {
                            doArm = true;
                        }
                        break;
                    case NONE:
                        doArm = true;
                        break;
                    default:
                        throw new IllegalStateException(
                                "Unexpected significance level " + significance.getConsequenceLevel());
                    }

                    if (doArm) {
                        log.info(String.format("Command armed %s", command));
                        command.setStackedState(StackedState.ARMED);
                        view.refreshState();
                    }
                });
            } else {
                Display.getDefault().asyncExec(() -> {
                    command.setStackedState(StackedState.REJECTED);
                    view.clearArm();
                    view.refreshState();
                });
            }
        });
    }
}

@@ -264,24 +264,75 @@
 nException;%0A
+import org.eclipse.jface.dialogs.IDialogConstants;%0A
 import org.e
@@ -2830,103 +2830,42 @@
     
-if (MessageDialog.openConfirm(activeShell, %22Confirm%22,%0A                                level + %22
+String message = String.format(%22%25s
 : Ar
@@ -2906,26 +2906,31 @@
 mmand?%5Cn
-%22 +%0A      
+    %25s%5Cn%5Cn%25s%22,%0A
         
@@ -2957,18 +2957,14 @@
     
-  %22    %22 +
+level,
  com
@@ -3004,95 +3004,224 @@
 ng()
- + %22%5Cn%5Cn%22 +%0A                                        significance.getReasonForWarning())
+, significance.getReasonForWarning());%0A                        MessageDialog dialog = new ConfirmDialogWithCancelDefault(activeShell, %22Confirm%22, message);%0A                        if (dialog.open() == MessageDialog.OK
 ) %7B%0A
@@ -4172,11 +4172,486 @@
 );%0A    %7D
+%0A%0A    private static class ConfirmDialogWithCancelDefault extends MessageDialog %7B%0A%0A        public ConfirmDialogWithCancelDefault(Shell parentShell, String title, String message) %7B%0A            super(parentShell, title, null, message, MessageDialog.CONFIRM, new String%5B%5D %7B%0A                    IDialogConstants.OK_LABEL,%0A                    IDialogConstants.CANCEL_LABEL,%0A            %7D, 1 /* cancel */);%0A            // setShellStyle(getShellStyle() %7C SWT.SHEET);%0A        %7D%0A    %7D
 %0A%7D%0A

Make Cancel the default button when confirming significant commands