/*
 * This file is part of Bisq.
 *
 * Bisq is free software: you can redistribute it and/or modify it
 * under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or (at
 * your option) any later version.
 *
 * Bisq is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
 * License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with Bisq. If not, see <http://www.gnu.org/licenses/>.
 */

package bisq.desktop.main.overlays.windows;

import bisq.desktop.components.AutoTooltipButton;
import bisq.desktop.components.InputTextField;
import bisq.desktop.main.overlays.Overlay;
import bisq.desktop.main.overlays.popups.Popup;

import bisq.core.alert.PrivateNotificationPayload;
import bisq.core.locale.Res;

import bisq.network.p2p.NodeAddress;
import bisq.network.p2p.SendMailboxMessageListener;

import bisq.common.app.DevEnv;
import bisq.common.crypto.PubKeyRing;
import bisq.common.util.Tuple2;

import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;

import javafx.geometry.Insets;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static bisq.desktop.util.FormBuilder.addLabelInputTextField;
import static bisq.desktop.util.FormBuilder.addLabelTextArea;

public class SendPrivateNotificationWindow extends Overlay<SendPrivateNotificationWindow> {
    private static final Logger log = LoggerFactory.getLogger(SendPrivateNotificationWindow.class);

    private final PubKeyRing pubKeyRing;
    private final NodeAddress nodeAddress;
    private final boolean useDevPrivilegeKeys;
    private SendPrivateNotificationHandler sendPrivateNotificationHandler;


    ///////////////////////////////////////////////////////////////////////////////////////////
    // Interface
    ///////////////////////////////////////////////////////////////////////////////////////////

    public interface SendPrivateNotificationHandler {
        @SuppressWarnings("BooleanMethodIsAlwaysInverted")
        boolean handle(PrivateNotificationPayload privateNotification, PubKeyRing pubKeyRing,
                       NodeAddress nodeAddress, String privKey, SendMailboxMessageListener sendMailboxMessageListener);
    }


    ///////////////////////////////////////////////////////////////////////////////////////////
    // Public API
    ///////////////////////////////////////////////////////////////////////////////////////////


    public SendPrivateNotificationWindow(PubKeyRing pubKeyRing, NodeAddress nodeAddress, boolean useDevPrivilegeKeys) {
        this.pubKeyRing = pubKeyRing;
        this.nodeAddress = nodeAddress;
        this.useDevPrivilegeKeys = useDevPrivilegeKeys;
        type = Type.Attention;
    }

    public void show() {
        if (headLine == null)
            headLine = Res.get("sendPrivateNotificationWindow.headline");

        width = 800;
        createGridPane();
        addHeadLine();
        addSeparator();
        addContent();
        applyStyles();
        display();
    }

    public SendPrivateNotificationWindow onAddAlertMessage(SendPrivateNotificationHandler sendPrivateNotificationHandler) {
        this.sendPrivateNotificationHandler = sendPrivateNotificationHandler;
        return this;
    }


    ///////////////////////////////////////////////////////////////////////////////////////////
    // Protected
    ///////////////////////////////////////////////////////////////////////////////////////////

    @Override
    protected void setupKeyHandler(Scene scene) {
        if (!hideCloseButton) {
            scene.setOnKeyPressed(e -> {
                if (e.getCode() == KeyCode.ESCAPE) {
                    e.consume();
                    doClose();
                }
            });
        }
    }

    private void addContent() {
        InputTextField keyInputTextField = addLabelInputTextField(gridPane, ++rowIndex,
                Res.get("shared.unlock"), 10).second;
        if (useDevPrivilegeKeys)
            keyInputTextField.setText(DevEnv.DEV_PRIVILEGE_PRIV_KEY);

        Tuple2<Label, TextArea> labelTextAreaTuple2 = addLabelTextArea(gridPane, ++rowIndex,
                Res.get("sendPrivateNotificationWindow.privateNotification"),
                Res.get("sendPrivateNotificationWindow.enterNotification"));
        TextArea alertMessageTextArea = labelTextAreaTuple2.second;
        Label first = labelTextAreaTuple2.first;
        first.setMinWidth(200);

        Button sendButton = new AutoTooltipButton(Res.get("sendPrivateNotificationWindow.send"));
        sendButton.setOnAction(e -> {
            if (alertMessageTextArea.getText().length() > 0 && keyInputTextField.getText().length() > 0) {
                if (!sendPrivateNotificationHandler.handle(
                        new PrivateNotificationPayload(alertMessageTextArea.getText()),
                        pubKeyRing,
                        nodeAddress,
                        keyInputTextField.getText(),
                        new SendMailboxMessageListener() {
                            @Override
                            public void onArrived() {
                                log.info("{} arrived at peer {}.",
                                        message.getClass().getSimpleName(), nodeAddress);
                                new Popup<>().feedback(Res.get("shared.messageArrived"))
                                        .onClose(SendPrivateNotificationWindow.this::hide).show();
                            }

                            @Override
                            public void onStoredInMailbox() {
                                log.info("{} stored in mailbox for peer {}.",
                                        message.getClass().getSimpleName(), nodeAddress);
                                new Popup<>().feedback(Res.get("shared.messageStoredInMailbox"))
                                        .onClose(SendPrivateNotificationWindow.this::hide).show();
                            }

                            @Override
                            public void onFault(String errorMessage) {
                                log.error("{} failed: Peer {}, errorMessage={}",
                                        message.getClass().getSimpleName(), nodeAddress, errorMessage);
                                new Popup<>().feedback(Res.get("shared.messageSendingFailed", errorMessage))
                                        .onClose(SendPrivateNotificationWindow.this::hide).show();
                            }
                        }))
                    new Popup<>().warning(Res.get("shared.invalidKey")).width(300).onClose(this::blurAgain).show();
            }
        });

        closeButton = new AutoTooltipButton(Res.get("shared.close"));
        closeButton.setOnAction(e -> {
            hide();
            closeHandlerOptional.ifPresent(Runnable::run);
        });

        HBox hBox = new HBox();
        hBox.setSpacing(10);
        GridPane.setRowIndex(hBox, ++rowIndex);
        GridPane.setColumnIndex(hBox, 1);
        hBox.getChildren().addAll(sendButton, closeButton);
        gridPane.getChildren().add(hBox);
        GridPane.setMargin(hBox, new Insets(10, 0, 0, 0));
    }


}

@@ -5075,17 +5075,8 @@
     
-if (!send
 Priv
@@ -5094,47 +5094,37 @@
 tion
-Handler.handle(%0A                       
+Payload privateNotification =
  new
@@ -5182,16 +5182,121 @@
 tText())
+;%0A                if (!sendPrivateNotificationHandler.handle(%0A                        privateNotification
 ,%0A      
@@ -5612,107 +5612,55 @@
 fo(%22
-%7B%7D arrived at peer %7B%7D.%22,%0A                                        message.getClass().getSimpleName()
+PrivateNotificationPayload arrived at peer %7B%7D.%22
 , no
@@ -6032,18 +6032,42 @@
 g.info(%22
-%7B%7D
+PrivateNotificationPayload
  stored 
@@ -6095,84 +6095,8 @@
 %7D.%22,
-%0A                                        message.getClass().getSimpleName(),
  nod
@@ -6485,18 +6485,42 @@
 .error(%22
-%7B%7D
+PrivateNotificationPayload
  failed:
@@ -6546,18 +6546,30 @@
 age=%7B%7D%22,
-%0A
  
+nodeAddress,%0A
         
@@ -6603,56 +6603,8 @@
     
-message.getClass().getSimpleName(), nodeAddress,
  err

Fix nullpointer