package be.iminds.ilabt.jfed.experimenter_gui.slice;

import be.iminds.ilabt.jfed.experimenter_gui.util.ui.MacWithDotsBinding;
import be.iminds.ilabt.jfed.experimenter_gui.util.ui.ReadOnlyTextFieldTableCell;
import be.iminds.ilabt.jfed.highlevel.model.Slice;
import be.iminds.ilabt.jfed.rspec.model.BasicStringRspec;
import be.iminds.ilabt.jfed.rspec.model.RspecInterface;
import be.iminds.ilabt.jfed.rspec.model.javafx_impl.FXRspecInterface;
import be.iminds.ilabt.jfed.rspec.model.javafx_impl.FXRspecNode;
import be.iminds.ilabt.jfed.ui.javafx.FXMLUtil;
import be.iminds.ilabt.jfed.ui.javafx.GlyphUtils;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.DoubleBinding;
import javafx.beans.property.SimpleStringProperty;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;
import javafx.util.Pair;
import org.controlsfx.glyphfont.FontAwesome;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.List;

/**
 * A dialog that shows some simple information about a node: authentication-type, hostname, login and port
 * <p>
 * User: twalcari
 * Date: 1/17/14
 * Time: 10:33 AM
 */
public class NodePropertiesDialog extends GridPane {
    private static final Logger LOG = LoggerFactory.getLogger(NodePropertiesDialog.class);

    private final Slice slice;
    private final FXRspecNode node;
    private final BasicStringRspec.LoginService loginService;

    @FXML
    private Label authenticationTypeLabel;
    @FXML
    private TextField hostnameTextField;
    @FXML
    private TextField usernameTextField;
    @FXML
    private TextField portTextField;

    @FXML
    private TableView<Pair<FXRspecInterface, FXRspecInterface.IpAddress>> interfacesTableView;

    @FXML
    private TableColumn<Pair<FXRspecInterface, FXRspecInterface.IpAddress>, String> ifaceIdTableColumn;
    @FXML
    private TableColumn<Pair<FXRspecInterface, FXRspecInterface.IpAddress>, String> ifaceIpTableColumn;
    @FXML
    private TableColumn<Pair<FXRspecInterface, FXRspecInterface.IpAddress>, String> ifaceNetmaskTableColumn;
    @FXML
    private TableColumn<Pair<FXRspecInterface, FXRspecInterface.IpAddress>, String> ifaceMacTableColumn;
    @FXML
    private TableColumn<Pair<FXRspecInterface, FXRspecInterface.IpAddress>, String> ifaceLinkTableColumn;


    private final Dialog<ButtonType> dialog;

    NodePropertiesDialog(@Nonnull Slice slice, @Nonnull FXRspecNode node,
                         @Nonnull BasicStringRspec.LoginService loginService) {
        this.slice = slice;
        this.node = node;
        this.loginService = loginService;

        //initialize the Scene
        FXMLUtil.injectFXML(this);

        DoubleBinding tableWidth = interfacesTableView.widthProperty().subtract(4);

        ifaceIdTableColumn.prefWidthProperty().bind(tableWidth.multiply(0.125));
        ifaceIpTableColumn.prefWidthProperty().bind(tableWidth.multiply(0.25));
        ifaceNetmaskTableColumn.prefWidthProperty().bind(tableWidth.multiply(0.25));
        ifaceMacTableColumn.prefWidthProperty().bind(tableWidth.multiply(0.25));
        ifaceLinkTableColumn.prefWidthProperty().bind(tableWidth.multiply(0.125));

        ifaceIdTableColumn.setCellValueFactory(param -> param.getValue().getKey().clientIdProperty());
        ifaceMacTableColumn.setCellValueFactory(param -> new MacWithDotsBinding(param.getValue().getKey().macAddressProperty()));
        ifaceIpTableColumn.setCellValueFactory(param -> new SimpleStringProperty(
                param.getValue() != null ? param.getValue().getValue().getAddress() : ""));
        ifaceNetmaskTableColumn.setCellValueFactory(param -> new SimpleStringProperty(
                param.getValue() != null ? param.getValue().getValue().getNetmask() : ""));
        ifaceLinkTableColumn.setCellValueFactory(param -> new SimpleStringProperty(
                param.getValue() != null && param.getValue().getKey().getLink() != null ?
                        param.getValue().getKey().getLink().getClientId() : ""
        ));


        interfacesTableView.prefHeightProperty().bind(Bindings.size(interfacesTableView.getItems()).multiply(28).add(25 /*header */ + 12 /*safety margin */));

        ifaceIpTableColumn.setCellFactory(ReadOnlyTextFieldTableCell.forTableColumn());
        ifaceNetmaskTableColumn.setCellFactory(ReadOnlyTextFieldTableCell.forTableColumn());
        ifaceMacTableColumn.setCellFactory(ReadOnlyTextFieldTableCell.forTableColumn());


        authenticationTypeLabel.setText(loginService.getAuthentication());
        hostnameTextField.setText(loginService.getHostname());
        portTextField.setText(loginService.getPort() + "");
        usernameTextField.setText(loginService.getUsername());

        List<Pair<FXRspecInterface, FXRspecInterface.IpAddress>> ifaceWithAddressCombos =
                new ArrayList<>();

        for (FXRspecInterface iface : node.getInterfaces()) {
            if (!iface.getIpAddresses().isEmpty()) {
                for (RspecInterface.IpAddress ipAddress : iface.getIpAddresses()) {
                    ifaceWithAddressCombos.add(new Pair<>(iface, ipAddress));
                }
            } else {
                ifaceWithAddressCombos.add(new Pair<>(iface, null));
            }
        }

        if (ifaceWithAddressCombos.isEmpty()) {
            interfacesTableView.setVisible(false);
            interfacesTableView.setManaged(false);
        } else {
            interfacesTableView.getItems().addAll(ifaceWithAddressCombos);
        }


        DialogPane dialogPane = new DialogPane();
        dialogPane.setContent(this);
        dialogPane.setHeaderText("Properties of " + node.getClientId());
        dialogPane.setGraphic(GlyphUtils.createDialogGlyph(FontAwesome.Glyph.INFO, Color.BLACK));
        dialogPane.getButtonTypes().setAll(ButtonType.CLOSE);

        //initialize dialog
        dialog = new javafx.scene.control.Dialog<>();
        dialog.setDialogPane(dialogPane);
        dialog.setTitle(dialogPane.getHeaderText());
        dialog.setHeaderText(dialog.getTitle());
        dialog.setResizable(true);


    }


    public void showDialog() {
        dialog.show();
    }

}
