/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2022 Red Hat, Inc., and individual contributors
 * as indicated by the @author tags.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

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.PropertiesFileConfig;

import javax.swing.ButtonGroup;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
import javax.swing.filechooser.FileNameExtensionFilter;

import java.awt.Color;
import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;

import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

import static javax.swing.JFileChooser.FILES_ONLY;
import static org.jboss.installer.common.UiResources.addField;
import static org.jboss.installer.common.UiResources.createDropdown;
import static org.jboss.installer.common.UiResources.createFieldLabelWithColonSuffix;
import static org.jboss.installer.common.UiResources.createRadioButton;
import static org.jboss.installer.common.UiResources.createTextField;
import static org.jboss.installer.common.UiResources.initializeConstraints;

public class PropertiesSecurityDomainPanel extends JPanel {

    public static final Color DEACTIVATED_PANEL_COLOR = new Color(250, 250, 250);
    public static final String FILE_BROWSE_KEY = "generic.browse";
    public static final String GENERIC_NO = "generic.no";
    public static final String GENERIC_YES = "generic.yes";
    public static final String GROUPS_FILE_LABEL = "security_domain_screen.properties.groups.file.label";
    public static final String USERS_FILE_LABEL = "security_domain_screen.properties.users.file.label";
    public static final String PLAIN_TEXT_LABEL = "security_domain_screen.properties.plain_text";
    public static final String HASH_SET_DESCRIPTION = "security_domain_screen.properties.hash_charset.description";
    public static final String HASH_ENC_DESCRIPTION = "security_domain_screen.properties.hash_enc.description";

    private final LanguageUtils langUtils;
    private final Path baseFolder;
    private final FileChooserPanel usersFileField;
    private final FileChooserPanel groupsFileField;
    private JRadioButton plainTextYesButton;
    private JRadioButton plainTextNoButton;
    private final JComboBox hashEncField;
    private final JTextField hashCharsetField = createTextField("UTF-8");

    public PropertiesSecurityDomainPanel(LanguageUtils langUtils, Path baseFolder) {
        this.langUtils = langUtils;
        this.setLayout(new GridBagLayout());
        this.baseFolder = baseFolder;
        this.hashEncField = createDropdown(
                new String[]{langUtils.getString("security_domain_screen.properties.hash_enc.hex"),
                        langUtils.getString("security_domain_screen.properties.hash_enc.base64"),
                });

        MnemonicUtils localMnemonic = new MnemonicUtils();
        this.usersFileField = FileChooserPanel.builder(langUtils, FILES_ONLY, localMnemonic)
                .baseFolder(baseFolder.resolve("standalone").resolve("configuration").resolve("example-users.properties").toString())
                .fileFilter(new FileNameExtensionFilter("Properties files (.properties)", "properties"))
                .build();
        this.groupsFileField = FileChooserPanel.builder(langUtils, FILES_ONLY, localMnemonic)
                .baseFolder(baseFolder.resolve("standalone").resolve("configuration").resolve("example-groups.properties").toString())
                .fileFilter(new FileNameExtensionFilter("Properties files (.properties)", "properties"))
                .build();

        initUI();
    }

    private void initUI() {
        final GridBagConstraints c = initializeConstraints();
        c.gridwidth = 1;
        c.insets = new Insets(5, 0, 0, 0);

        c.gridy++;
        addField(this, c, langUtils.getString(USERS_FILE_LABEL), langUtils.getString(USERS_FILE_LABEL + ".tooltip"), usersFileField);
        c.gridy++;
        addField(this, c, langUtils.getString(GROUPS_FILE_LABEL), langUtils.getString(GROUPS_FILE_LABEL + ".tooltip"), groupsFileField);

        final JPanel hashPanel = new JPanel(new GridBagLayout());
        c.gridwidth = 1;
        c.gridy++;
        final JLabel plainTextLabel = createFieldLabelWithColonSuffix(langUtils.getString(PLAIN_TEXT_LABEL));
        UiResources.setTooltip(plainTextLabel, langUtils.getString(PLAIN_TEXT_LABEL + ".tooltip"));
        this.add(plainTextLabel, c);
        final JPanel radioPanel = createYesNoRadioPanel();
        plainTextNoButton.addActionListener(e -> setPanelEnabled(plainTextNoButton.isSelected(), hashPanel));
        plainTextYesButton.addActionListener(e -> setPanelEnabled(plainTextNoButton.isSelected(), hashPanel));
        UiResources.setTooltip(plainTextNoButton, langUtils.getString(PLAIN_TEXT_LABEL + ".tooltip"));
        UiResources.setTooltip(plainTextYesButton, langUtils.getString(PLAIN_TEXT_LABEL + ".tooltip"));

        c.gridx = 1;
        this.add(radioPanel, c);
        c.gridx = 0;
        c.gridwidth = 2;

        hashPanel.setEnabled(false);
        hashPanel.setBackground(DEACTIVATED_PANEL_COLOR);
        final GridBagConstraints c1 = initializeConstraints();
        final JLabel hashEncLabel = createFieldLabelWithColonSuffix(langUtils.getString(HASH_ENC_DESCRIPTION));
        UiResources.setTooltip(hashEncLabel, langUtils.getString(HASH_ENC_DESCRIPTION + ".tooltip"));
        hashPanel.add(hashEncLabel, c1);
        c1.gridx = 1;
        hashEncField.setEnabled(false);
        hashPanel.add(hashEncField, c1);
        UiResources.setTooltip(hashEncField, langUtils.getString(HASH_ENC_DESCRIPTION + ".tooltip"));
        c1.gridx = 0;

        c1.gridy++;
        final JLabel hashSetLabel = createFieldLabelWithColonSuffix(langUtils.getString(HASH_SET_DESCRIPTION));
        hashPanel.add(hashSetLabel, c1);
        UiResources.setTooltip(hashSetLabel, langUtils.getString(HASH_SET_DESCRIPTION + ".tooltip"));
        c1.gridx = 1;
        hashCharsetField.setEnabled(false);
        hashPanel.add(hashCharsetField, c1);
        UiResources.setTooltip(hashCharsetField, langUtils.getString(HASH_SET_DESCRIPTION + ".tooltip"));
        c1.gridx = 0;

        c.gridy++;
        this.add(hashPanel, c);
    }

    private JPanel createYesNoRadioPanel() {
        ButtonGroup bg = new ButtonGroup();
        plainTextYesButton = createRadioButton(langUtils.getString(GENERIC_YES), true);
        bg.add(plainTextYesButton);
        plainTextNoButton = createRadioButton(langUtils.getString(GENERIC_NO), false);
        bg.add(plainTextNoButton);
        final JPanel radioPanel = new JPanel();
        radioPanel.add(plainTextYesButton);
        radioPanel.add(plainTextNoButton);
        return radioPanel;
    }

    private void setPanelEnabled(boolean selected, JPanel hashPanel) {
        hashPanel.setEnabled(selected);
        hashPanel.setBackground(selected ? Color.WHITE : DEACTIVATED_PANEL_COLOR);
        for (Component component : hashPanel.getComponents()) {
            component.setEnabled(selected);
        }
    }

    PropertiesFileConfig getConfig() throws FileChooserPanel.InvalidPathException {
        final PropertiesFileConfig propertiesFileConfig = new PropertiesFileConfig();
        propertiesFileConfig.setUsersFilePath(StringUtils.isEmpty(usersFileField.getText())?null:Paths.get(usersFileField.asPath()));
        propertiesFileConfig.setGroupsFilePath(StringUtils.isEmpty(groupsFileField.getText())?null:Paths.get(groupsFileField.asPath()));
        propertiesFileConfig.setPlainText(plainTextYesButton.isSelected());
        propertiesFileConfig.setHashEncoding(hashEncField.getSelectedIndex() == 0 ? "hex" : "base64");
        propertiesFileConfig.setHashCharset(UiResources.readTextValue(hashCharsetField));
        return propertiesFileConfig;
    }

    Map<String, String> getAttributes() {
        final HashMap<String, String> attrs = new HashMap<>();
        try {
            final PropertiesFileConfig config = getConfig();
            attrs.put(langUtils.getString(USERS_FILE_LABEL), config.getUsersFilePath().toString());
            attrs.put(langUtils.getString(GROUPS_FILE_LABEL), config.getGroupsFilePath().toString());
            attrs.put(langUtils.getString(PLAIN_TEXT_LABEL), "" + config.isPlainText());
            if (!config.isPlainText()) {
                attrs.put(langUtils.getString(HASH_ENC_DESCRIPTION), config.getHashEncoding());
                attrs.put(langUtils.getString(HASH_SET_DESCRIPTION), config.getHashCharset());
            }
        } catch (FileChooserPanel.InvalidPathException e) {
            throw new RuntimeException(e);
        }
        return attrs;
    }
}
