package org.jboss.installer.screens.domain;

import org.apache.commons.lang3.StringUtils;
import org.jboss.installer.common.FileChooserPanel;
import org.jboss.installer.common.UiResources;
import org.jboss.installer.core.LanguageUtils;
import org.jboss.installer.core.MnemonicUtils;
import org.jboss.installer.postinstall.task.secdom.CertSecurity;

import javax.swing.Box;
import javax.swing.ButtonGroup;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.stream.Collectors;

import static javax.swing.JFileChooser.FILES_ONLY;

public class CertificateSecurityDomainPanel extends JPanel {

    public static final String TRUST_STORE_PASSWORD_KEY = "security_domain_screen.cert.truststore.password.label";
    public static final String TRUST_STORE_PATH_KEY = "security_domain_screen.cert.truststore.path.label";
    public static final String FILTER_HEADER_KEY = "security_domain_screen.cert.filter.header";
    public static final String FILTER_VALUE_KEY = "security_domain_screen.cert.filter.value.label";
    public static final String ROLES_KEY = "security_domain_screen.cert.roles.label";
    public static final String START_SEGMENT_KEY = "security_domain_screen.cert.start_segment.label";
    public static final String MAX_SEGMENT_KEY = "security_domain_screen.cert.max_segment.label";
    public static final String FILTER_TYPE_KEY = "security_domain_screen.cert.filter.type.label";

    private final LanguageUtils langUtils;
    private JRadioButton nameRadioButton = UiResources.createRadioButton("name", false);
    private JRadioButton oidRadioButton = UiResources.createRadioButton("oid", true);
    private JPasswordField trustStorePasswordField = UiResources.createPasswordField();
    private FileChooserPanel trustorePathPanel;
    private JTextField rolesField = UiResources.createTextField("Admin, Guest");
    private JTextField startSegmentField = UiResources.createNumberField(0);
    private JTextField maxSegmentsField = UiResources.createNumberField(1);
    private JTextField filterExpressionField = UiResources.createTextField("2.5.4.3");

    {
        ButtonGroup radioButtonGroup = new ButtonGroup();
        radioButtonGroup.add(oidRadioButton);
        radioButtonGroup.add(nameRadioButton);
    }

    public CertificateSecurityDomainPanel(LanguageUtils langUtils, MnemonicUtils mnemonicUtils) {
        this.langUtils = langUtils;
        this.setLayout(new GridBagLayout());

        this.trustorePathPanel = FileChooserPanel.builder(langUtils, FILES_ONLY, mnemonicUtils)
                .rawButtonText("Search")
                .fileFilter(new FileNameExtensionFilter("KeyStore", "jks")).build();
        initUI();
    }

    private void initUI() {
        this.setBorder(UiResources.spacedBorder());
        GridBagConstraints c = UiResources.initializeConstraints();
        c.insets = new Insets(5, 0, 0, 0);

        UiResources.addField(this, c, langUtils.getString(TRUST_STORE_PATH_KEY),
                langUtils.getString(TRUST_STORE_PATH_KEY + ".tooltip"), trustorePathPanel);

        UiResources.addField(this, c, langUtils.getString(TRUST_STORE_PASSWORD_KEY),
                langUtils.getString(TRUST_STORE_PASSWORD_KEY + ".tooltip"), trustStorePasswordField);

        UiResources.addField(this, c, langUtils.getString(ROLES_KEY),
                langUtils.getString(ROLES_KEY + ".tooltip"), rolesField);

        c.gridy++;
        c.gridwidth = 2;
        this.add(UiResources.createFieldLabel(langUtils.getString(FILTER_HEADER_KEY)), c);

        c.gridwidth = 1;

        final JPanel selector = new JPanel(new GridBagLayout());
        GridBagConstraints sc = UiResources.initializeConstraints();
        sc.gridx = 0;
        selector.add(oidRadioButton, sc);
        sc.gridx = 1;
        selector.add(nameRadioButton, sc);
        sc.gridx = 2;
        sc.weightx = 10;
        selector.add(Box.createHorizontalBox(), sc);

        c.gridy++;
        final JLabel selectorLabel = UiResources.createFieldLabel(langUtils.getString(FILTER_TYPE_KEY) + ":");
        this.add(selectorLabel, c);
        c.gridx = 1;
        this.add(selector, c);
        c.gridx = 0;
        UiResources.setTooltip(selectorLabel, langUtils.getString(FILTER_TYPE_KEY + ".tooltip"));
        UiResources.setTooltip(oidRadioButton, langUtils.getString(FILTER_TYPE_KEY + ".tooltip"));
        UiResources.setTooltip(nameRadioButton, langUtils.getString(FILTER_TYPE_KEY + ".tooltip"));

        UiResources.addField(this, c, langUtils.getString(FILTER_VALUE_KEY), langUtils.getString(FILTER_VALUE_KEY + ".tooltip"), filterExpressionField);

        UiResources.addField(this, c, langUtils.getString(START_SEGMENT_KEY), langUtils.getString(START_SEGMENT_KEY + ".tooltip"), startSegmentField);
        UiResources.addField(this, c, langUtils.getString(MAX_SEGMENT_KEY), langUtils.getString(MAX_SEGMENT_KEY + ".tooltip"), maxSegmentsField);
    }

    public CertSecurity.CertificateConfig getConfig(String domainName) throws FileChooserPanel.InvalidPathException {
        final CertSecurity.CertificateConfig certificateConfig = new CertSecurity.CertificateConfig();
        certificateConfig.setTrustStorePassword(new String(trustStorePasswordField.getPassword()).trim());
        certificateConfig.setTrustStorePath(trustorePathPanel.getText()==null?null:Paths.get(trustorePathPanel.asPath()));
        certificateConfig.setRoles(Arrays.stream(rolesField.getText().split(","))
                .map(String::trim)
                .filter(StringUtils::isNotEmpty)
                .collect(Collectors.toList())
                .toArray(new String[]{}));
        certificateConfig.setStartSegments(StringUtils.isNotEmpty(startSegmentField.getText())?Integer.parseInt(startSegmentField.getText()):null);
        certificateConfig.setMaximumSegments(StringUtils.isNotEmpty(maxSegmentsField.getText())?Integer.parseInt(maxSegmentsField.getText()):null);
        certificateConfig.setApplicationDomainName(domainName);
        certificateConfig.setFilterExpression(UiResources.readTextValue(filterExpressionField));
        certificateConfig.setUseOid(oidRadioButton.isSelected());
        return certificateConfig;
    }

}
