/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * 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.jboss.installer.common.UiResources;
import org.jboss.installer.core.LanguageUtils;
import org.jboss.installer.postinstall.task.secdom.DatabaseSecurity;

import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

import java.awt.Insets;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.util.Locale;

import static org.jboss.installer.postinstall.task.secdom.DatabaseSecurity.JdbcConfig.MapperType.Digest;
import static org.jboss.installer.postinstall.task.secdom.DatabaseSecurity.JdbcConfig.MapperType.SaltedDigest;

public class SelectorPanel extends JPanel {

    public static final String PASSWORD_SELECTOR_LABEL = "security_domain_screen.jdbc.password_selector.label";
    public static final String GROUP_SELECTOR_LABEL = "security_domain_screen.jdbc.group_selector.label";
    public static final String SALT_SELECTOR_LABEL = "security_domain_screen.jdbc.salt_selector.label";
    public static final String HASH_ENC_LABEL = "security_domain_screen.jdbc.hash_enc.label";
    protected static final String[] ENCODING_OPTIONS = {"Base64", "Hex"};
    public static final String SALT_ENCODING_LABEL = "security_domain_screen.jdbc.salt_enc.label";
    public static final String HASH_ALG_LABEL = "security_domain_screen.jdbc.hash_alg.label";

    private final LanguageUtils langUtils;
    private DatabaseSecurity.JdbcConfig.MapperType mapper = DatabaseSecurity.JdbcConfig.MapperType.Plain;
    private final JTextField passwordSelectorField;
    private final JTextField groupSelectorField;
    private final JTextField saltSelectorField;
    private final JComboBox<String> hashEncField;
    private final JComboBox<String> saltEncField;
    private final JComboBox digestHashAlgField;
    private final JComboBox saltedDigestHashAlg;


    SelectorPanel(LanguageUtils langUtils) {
        this.langUtils = langUtils;
        this.setLayout(new GridBagLayout());

        passwordSelectorField = UiResources.createTextField("1");
        groupSelectorField = UiResources.createTextField("2");
        saltSelectorField = UiResources.createTextField("3");
        hashEncField = UiResources.createDropdown(ENCODING_OPTIONS);
        saltEncField = UiResources.createDropdown(ENCODING_OPTIONS);
        digestHashAlgField = UiResources.createDropdown(new String[]{
                "simple-digest-md2", "simple-digest-md5", "simple-digest-sha-1",
                "simple-digest-sha-256", "simple-digest-sha-384", "simple-digest-sha-512"
        });
        saltedDigestHashAlg = UiResources.createDropdown(new String[]{
                "password-salt-digest-md5", "password-salt-digest-sha-1", "password-salt-digest-sha-256",
                "password-salt-digest-sha-384", "password-salt-digest-sha-512", "salt-password-digest-md5",
                "salt-password-digest-sha-1", "salt-password-digest-sha-256", "salt-password-digest-sha-384",
                "salt-password-digest-sha-512"
        });

        populatePanel();
    }

    private void populatePanel() {
        final GridBagConstraints c = UiResources.initializeConstraints();
        c.insets = new Insets(5, 0, 0, 0);

        c.gridwidth = 1;
        final JLabel passwordSelectorLabel = UiResources.createFieldLabelWithColonSuffix(langUtils.getString(PASSWORD_SELECTOR_LABEL));
        this.add(passwordSelectorLabel, c);
        c.gridx = 1;
        this.add(passwordSelectorField, c);
        UiResources.setTooltip(passwordSelectorLabel, langUtils.getString(PASSWORD_SELECTOR_LABEL + ".tooltip"));
        UiResources.setTooltip(passwordSelectorField, langUtils.getString(PASSWORD_SELECTOR_LABEL + ".tooltip"));
        c.gridx = 0;

        c.gridy++;
        final JLabel groupSelectorLabel = UiResources.createFieldLabelWithColonSuffix(langUtils.getString(GROUP_SELECTOR_LABEL));
        this.add(groupSelectorLabel, c);
        c.gridx = 1;
        this.add(groupSelectorField, c);
        UiResources.setTooltip(groupSelectorLabel, langUtils.getString(GROUP_SELECTOR_LABEL + ".tooltip"));
        UiResources.setTooltip(groupSelectorField, langUtils.getString(GROUP_SELECTOR_LABEL + ".tooltip"));
        c.gridx = 0;

        if (mapper == SaltedDigest) {
            c.gridy++;
            final JLabel saltSelectorLabel = UiResources.createFieldLabelWithColonSuffix(langUtils.getString(SALT_SELECTOR_LABEL));
            this.add(saltSelectorLabel, c);
            c.gridx = 1;
            this.add(saltSelectorField, c);
            UiResources.setTooltip(saltSelectorLabel, langUtils.getString(SALT_SELECTOR_LABEL + ".tooltip"));
            UiResources.setTooltip(saltSelectorField, langUtils.getString(SALT_SELECTOR_LABEL + ".tooltip"));
            c.gridx = 0;

            c.gridy++;
            final JLabel hashEncLabel = UiResources.createFieldLabelWithColonSuffix(langUtils.getString(HASH_ENC_LABEL));
            this.add(hashEncLabel, c);
            c.gridx = 1;
            this.add(hashEncField, c);
            UiResources.setTooltip(hashEncLabel, langUtils.getString(HASH_ENC_LABEL + ".tooltip"));
            UiResources.setTooltip(hashEncField, langUtils.getString(HASH_ENC_LABEL + ".tooltip"));
            c.gridx = 0;

            c.gridy++;
            final JLabel saltEncLabel = UiResources.createFieldLabelWithColonSuffix(langUtils.getString(SALT_ENCODING_LABEL));
            this.add(saltEncLabel, c);
            c.gridx = 1;
            this.add(saltEncField, c);
            UiResources.setTooltip(saltEncLabel, langUtils.getString(SALT_ENCODING_LABEL + ".tooltip"));
            UiResources.setTooltip(saltEncField, langUtils.getString(SALT_ENCODING_LABEL + ".tooltip"));
            c.gridx = 0;

            c.gridy++;
            final JLabel saltedDifestHashLabel = UiResources.createFieldLabelWithColonSuffix(langUtils.getString(HASH_ALG_LABEL));
            this.add(saltedDifestHashLabel, c);
            c.gridx = 1;
            this.add(saltedDigestHashAlg, c);
            UiResources.setTooltip(saltedDifestHashLabel, langUtils.getString(HASH_ALG_LABEL + ".tooltip"));
            UiResources.setTooltip(saltedDigestHashAlg, langUtils.getString(HASH_ALG_LABEL + ".tooltip"));
            c.gridx = 0;
            c.gridwidth = 2;
        }

        if (mapper == Digest) {
            c.gridy++;
            final JLabel hashEncLabel = UiResources.createFieldLabelWithColonSuffix(langUtils.getString(HASH_ENC_LABEL));
            this.add(hashEncLabel, c);
            c.gridx = 1;
            this.add(hashEncField, c);
            UiResources.setTooltip(hashEncLabel, langUtils.getString(HASH_ENC_LABEL + ".tooltip"));
            UiResources.setTooltip(hashEncField, langUtils.getString(HASH_ENC_LABEL + ".tooltip"));
            c.gridx = 0;

            c.gridy++;
            final JLabel digestHashAlgLabel = UiResources.createFieldLabelWithColonSuffix(langUtils.getString(HASH_ALG_LABEL));
            this.add(digestHashAlgLabel, c);
            c.gridx = 1;
            this.add(digestHashAlgField, c);
            UiResources.setTooltip(digestHashAlgLabel, langUtils.getString(HASH_ALG_LABEL + ".tooltip"));
            UiResources.setTooltip(digestHashAlgField, langUtils.getString(HASH_ALG_LABEL + ".tooltip"));
            c.gridx = 0;
            c.gridwidth = 2;
        }
    }

    void mapperChanged(DatabaseSecurity.JdbcConfig.MapperType mapper) {
        this.mapper = mapper;
        this.removeAll();
        populatePanel();
        this.revalidate();
    }

    void recordUpdates(DatabaseSecurity.JdbcConfig config) {
        config.setPasswordIndex(UiResources.readTextValue(passwordSelectorField));
        config.setGroupIndex(UiResources.readTextValue(groupSelectorField));
        config.setSaltIndex(UiResources.readTextValue(saltSelectorField));
        config.setHashEncoding(getEncodingValue(hashEncField));
        config.setSaltEncoding(getEncodingValue(saltEncField));
        switch (mapper) {
            case SaltedDigest:
                config.setEncodingAlgorithm((String) saltedDigestHashAlg.getSelectedItem());
                break;
            case Digest:
                config.setEncodingAlgorithm((String) digestHashAlgField.getSelectedItem());
                break;
            default:
                config.setEncodingAlgorithm(null);
                break;
        }
    }

    private String getEncodingValue(JComboBox<String> encField) {
        if (encField.getSelectedItem() == null) {
            throw new RuntimeException("No value selected in the encoding field");
        }
        return ((String) encField.getSelectedItem()).toLowerCase(Locale.ENGLISH);
    }
}
