/**
 * 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.postinstall.ldap;

import static org.jboss.installer.postinstall.task.utils.ModelUtils.createEmptyOperation;
import static org.jboss.installer.postinstall.task.utils.ModelUtils.pathAddress;

import org.jboss.dmr.ModelNode;
import org.jboss.installer.postinstall.task.CredentialStoreConfig;
import org.jboss.installer.postinstall.task.LDAPManagementAuthConfig;

import java.util.Optional;

public class LdapSecurity {

    public static final String ALIAS_SUFFIX = "-secret";
    private static final String EMPTY_RDN = " ";

    public ModelNode createDirContext(LdapModel config, Optional<CredentialStoreConfig> storeConfig) {
        final String connection = config.getConnectionName();

        ModelNode op = createEmptyOperation("add",
                pathAddress("subsystem", "elytron").add("dir-context", connection));
        op.get("url").set(config.getUrl());
        op.get("principal").set(config.getLdapUsername());
        final ModelNode credRefNode = op.get("credential-reference");
        if (storeConfig.isPresent()) {
            credRefNode.get("alias").set(config.getConnectionName() + ALIAS_SUFFIX);
            credRefNode.get("store").set(storeConfig.get().getStoreName());
        } else {
            credRefNode.get("clear-text").set(config.getLdapPassword());
        }

        return op;
    }

    public ModelNode createLdapRealm(LdapModel config) {
        ModelNode op = createEmptyOperation("add",
                pathAddress("subsystem", "elytron").add("ldap-realm", config.getRealmName()));
        op.get("dir-context").set(config.getConnectionName());

        final ModelNode idMapping = op.get("identity-mapping");
        idMapping.get("use-recursive-search").set(config.isRecursive());
        idMapping.get("search-base-dn").set(config.getSearchBaseDn());
        if (config.getFilterType() == LDAPManagementAuthConfig.FilterType.USERNAME) {
            idMapping.get("rdn-identifier").set(config.getUserFilter());
        } else {
            idMapping.get("rdn-identifier").set(EMPTY_RDN);
            idMapping.get("filter-name").set(config.getUserFilter());
        }
        final ModelNode pwdMapperNode = idMapping.get("user-password-mapper");
        pwdMapperNode.get("from").set(config.getPasswordAttribute());

        final ModelNode roleMapNode = new ModelNode();
        if (config.getRoleBaseDn() != null) {
            roleMapNode.get("filter-base-dn").set(config.getRoleBaseDn());
        }
        if (config.getRoleFilter() != null) {
            roleMapNode.get("filter").set(config.getRoleFilter());
        }
        if (config.getRoleAttribute() != null) {
            roleMapNode.get("from").set(config.getRoleAttribute());
        }
        roleMapNode.get("to").set("groups");
        idMapping.get("attribute-mapping").add(roleMapNode);

        return op;
    }

}
