/**
 * 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.ldap.LdapModel;
import org.jboss.installer.postinstall.task.LDAPManagementAuthConfig;
import org.jboss.installer.postinstall.task.SecurityDomainConfig;

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

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.util.HashMap;
import java.util.Map;

import static org.jboss.installer.screens.LDAPConnectionScreen.LDAP_SCREEN_LABEL_DIRECTORY_SERVER;
import static org.jboss.installer.screens.LDAPConnectionScreen.LDAP_SCREEN_LABEL_DISTINGUISHED_NAME;
import static org.jboss.installer.screens.LDAPConnectionScreen.LDAP_SCREEN_LABEL_DN_PASSWORD;
import static org.jboss.installer.screens.LDAPSecurityRealmScreen.LDAP_REALM_SCREEN_BASE_DN_LABEL;
import static org.jboss.installer.screens.LDAPSecurityRealmScreen.LDAP_REALM_SCREEN_USERNAME_FILTER_LABEL;

public class LdapSecurityDomainPanel extends JPanel {
    public static final String LDAP_PASSWORD_ATTR_LABEL = "security_domain_screen.ldap.password_attr.label";
    public static final String LDAP_ROLE_FILTER_BASE_DN_LABEL = "security_domain_screen.ldap.roles_filter_base.label";
    public static final String LDAP_ROLES_FILTER_LABEL = "security_domain_screen.ldap.roles_filter.label";
    public static final String LDAP_ROLES_ATTR_LABEL = "security_domain_screen.ldap.roles_attr.label";
    private final LanguageUtils langUtils;
    private final GridBagConstraints c;
    private final JTextField ldapUrlField = UiResources.createTextField("ldap://127.0.0.1:10389");
    private final JTextField ldapUsernameField = UiResources.createTextField("uid=admin,ou=system");
    private final JTextField ldapPasswordField = UiResources.createPasswordField();
    private final JTextField searchBaseDnField = UiResources.createTextField("ou=Users,dc=example,dc=org");
    private final JTextField usernameAttrField = UiResources.createTextField("uid");
    private final JTextField passwordAttrField = UiResources.createTextField("userPassword");
    private final JTextField roleFilterBaseDnField = UiResources.createTextField("ou=Roles,dc=example,dc=org");
    private final JTextField rolesFilterField = UiResources.createTextField("(&(objectClass=groupOfNames)(member={1}))");
    private final JTextField rolesAttrField = UiResources.createTextField("cn");

    LdapSecurityDomainPanel(LanguageUtils langUtils) {
        this.langUtils = langUtils;
        this.setLayout(new GridBagLayout());
        c = UiResources.initializeConstraints();

        initUI();
    }

    private void initUI() {
        c.insets = new Insets(5, 0, 0, 0);
        createFieldRow(LDAP_SCREEN_LABEL_DIRECTORY_SERVER, ldapUrlField);

        createFieldRow(LDAP_SCREEN_LABEL_DISTINGUISHED_NAME, ldapUsernameField);

        createFieldRow(LDAP_SCREEN_LABEL_DN_PASSWORD, ldapPasswordField);

        createFieldRow(LDAP_REALM_SCREEN_BASE_DN_LABEL, searchBaseDnField);

        createFieldRow(LDAP_REALM_SCREEN_USERNAME_FILTER_LABEL, usernameAttrField);

        createFieldRow(LDAP_PASSWORD_ATTR_LABEL, passwordAttrField);

        createFieldRow(LDAP_ROLE_FILTER_BASE_DN_LABEL, roleFilterBaseDnField);

        createFieldRow(LDAP_ROLES_FILTER_LABEL, rolesFilterField);

        createFieldRow(LDAP_ROLES_ATTR_LABEL, rolesAttrField);
    }

    @Override
    public void requestFocus() {
        ldapUrlField.requestFocus();
    }

    private void createFieldRow(String text, JTextField field) {
        c.gridwidth = 1;
        final JLabel label = UiResources.createFieldLabelWithColonSuffix(langUtils.getString(text));
        this.add(label, c);
        c.gridx = 1;
        this.add(field, c);
        c.gridx = 0;
        c.gridwidth = 2;
        c.gridy++;

        UiResources.setTooltip(label, langUtils.getString(text));
        UiResources.setTooltip(field, langUtils.getString(text));
    }

    LdapModel getConfig(String domainName) {
        final LdapModel model = new LdapModel();
        model.setRealmName(domainName + SecurityDomainConfig.REALM_SUFFIX);
        model.setConnection(domainName + ".connection", UiResources.readTextValue(ldapUrlField),
                UiResources.readTextValue(ldapUsernameField), UiResources.readTextValue(ldapPasswordField));
        model.setUserFilter(LDAPManagementAuthConfig.FilterType.USERNAME, usernameAttrField.getText(),
                UiResources.readTextValue(searchBaseDnField), UiResources.readTextValue(passwordAttrField), true);
        model.setRole(UiResources.readTextValue(roleFilterBaseDnField), UiResources.readTextValue(rolesFilterField), UiResources.readTextValue(rolesAttrField));

        return model;
    }

    Map<String, String> getAttributes(String domainName) {
        final HashMap<String, String> attrs = new HashMap<>();
        final LdapModel config = getConfig(domainName);

        attrs.put(langUtils.getString(LDAP_SCREEN_LABEL_DIRECTORY_SERVER), config.getUrl());
        attrs.put(langUtils.getString(LDAP_ROLES_ATTR_LABEL), config.getRoleAttribute());
        attrs.put(langUtils.getString(LDAP_SCREEN_LABEL_DISTINGUISHED_NAME), config.getLdapUsername());
        attrs.put(langUtils.getString(LDAP_PASSWORD_ATTR_LABEL), config.getPasswordAttribute());

        attrs.put(langUtils.getString(LDAP_REALM_SCREEN_USERNAME_FILTER_LABEL), config.getLdapUsername());
        attrs.put(langUtils.getString(LDAP_ROLE_FILTER_BASE_DN_LABEL), config.getRoleBaseDn());
        attrs.put(langUtils.getString(LDAP_ROLES_FILTER_LABEL), config.getRoleFilter());
        attrs.put(langUtils.getString(LDAP_REALM_SCREEN_USERNAME_FILTER_LABEL), config.getUserFilter());
        attrs.put(langUtils.getString(LDAP_REALM_SCREEN_BASE_DN_LABEL), config.getSearchBaseDn());
        return attrs;
    }
}
