package be.iminds.ilabt.jfed.ui.javafx.probe_gui.credential_manipulation;

import be.iminds.ilabt.jfed.lowlevel.GeniUser;
import be.iminds.ilabt.jfed.lowlevel.GeniUserProvider;
import be.iminds.ilabt.jfed.ui.javafx.dialogs.JFDialogs;
import be.iminds.ilabt.jfed.util.GeniUrn;
import be.iminds.ilabt.jfed.util.IOUtils;
import be.iminds.ilabt.jfed.util.KeyUtil;
import javafx.fxml.FXML;
import javafx.scene.control.TextInputDialog;
import javafx.scene.layout.BorderPane;
import javafx.stage.FileChooser;
import javafx.stage.Window;
import org.slf4j.LoggerFactory;

import javax.inject.Inject;
import java.io.File;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.List;

/**
 * SavePemPanel
 */
public class SavePemPanelController {
    private static final org.slf4j.Logger LOG = LoggerFactory.getLogger(SavePemPanelController.class);

    private final GeniUserProvider geniUserProvider;

    @FXML
    private BorderPane root;

    @Inject
    public SavePemPanelController(GeniUserProvider geniUserProvider) {
        this.geniUserProvider = geniUserProvider;
    }


    private Window getWindow() {
        return root.getScene().getWindow();
    }

    public File saveToFile(String defaultFileName) {
        FileChooser fileChooser = new FileChooser();
        fileChooser.setInitialFileName(defaultFileName);
        File file = fileChooser.showSaveDialog(getWindow());
        return file;
    }

    public String getUsername() {
        if (!geniUserProvider.isUserLoggedIn())
            return null;
        return geniUserProvider.getLoggedInGeniUser().getUserUrn().getEncodedResourceName();
    }

    public String getNiceName() {
        if (!geniUserProvider.isUserLoggedIn())
            return null;
        GeniUrn userUrn = geniUserProvider.getLoggedInGeniUser().getUserUrn();
        return userUrn.getEncodedTopLevelAuthority() + "_" + userUrn.getEncodedResourceName();
    }

    public void saveWithPass() {
        JFDialogs.create()
                .owner(getWindow())
                .message("This is not yet implemented")
                .title("Unsupported operation")
                .showWarning();
    }

    public void saveWithoutPass() {
        File file = saveToFile(getNiceName() + ".pem");

        if (!geniUserProvider.isUserLoggedIn())
            return;

        GeniUser user = geniUserProvider.getLoggedInGeniUser();
        PrivateKey pk = user.getPrivateKey();
        String pkPem = new String(KeyUtil.privateKeyToAnyPem(pk));
        String certPem = KeyUtil.x509certificateChainToPem(user.getClientCertificateChain());
        String pem = pkPem + "\n" + certPem;

        IOUtils.stringToFile(file, pem);
    }

    public void savePKCS12() {
        File pkcs12File = saveToFile(getNiceName() + ".p12");

        if (!geniUserProvider.isUserLoggedIn())
            return;

        GeniUser user = geniUserProvider.getLoggedInGeniUser();
        PrivateKey pk = user.getPrivateKey();

        List<X509Certificate> certs = user.getClientCertificateChain();
        Certificate[] chain = new Certificate[certs.size()];
        for (int i = 0; i < certs.size(); i++) chain[i] = certs.get(i);

        TextInputDialog textInputDialog = new TextInputDialog();
        textInputDialog.setContentText("New password for PKCS12 file");
        textInputDialog.showAndWait().ifPresent(pass -> {
            char[] keyStorePass = pass.toCharArray();
            KeyStore keyStore = null;
            try {
                keyStore = KeyStore.getInstance("jks");
                keyStore.load(null/*inputstream*/, null/*pass*/);
                keyStore.setKeyEntry(getNiceName(), pk, keyStorePass/*pass*/, chain);

                byte[] pkcs12 = KeyUtil.keyStoreToPKCS12Bytes(keyStore, pass, pass);
                IOUtils.byteArrayToFile(pkcs12File, pkcs12);
                LOG.info("Saved user login as PKCS12 to " + pkcs12File + "  (" + pkcs12.length + " bytes)");
            } catch (Exception e) {
                LOG.error("Failed to convert and save PK12: " + e.getMessage(), e);
            }
        });

    }
}
