/*
 * 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.postinstall.task.impl.secdom;

import org.jboss.dmr.ModelNode;
import org.jboss.installer.postinstall.ldap.SecurityDomain;
import org.jboss.installer.postinstall.ldap.SecurityDomainModel;
import org.jboss.installer.postinstall.task.secdom.JdbcConfig;

import java.util.ArrayList;
import java.util.List;

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

public class DatabaseSecurity {

    public List<ModelNode> toOperations(String domainName, JdbcConfig jdbcConfig) {
        final ArrayList<ModelNode> ops = new ArrayList<>();
        final String datasourceName = jdbcConfig.getDatasourceName();
        final String sqlQuery = jdbcConfig.getSqlQuery();
        final JdbcConfig.MapperType mapperType = jdbcConfig.getMapperType();
        final String passwordIndex = jdbcConfig.getPasswordIndex();
        final String groupIndex = jdbcConfig.getGroupIndex();
        final String saltIndex = jdbcConfig.getSaltIndex();
        final String encodingAlgorithm = jdbcConfig.getEncodingAlgorithm();
        final String hashEncoding = jdbcConfig.getHashEncoding();
        final String saltEncoding = jdbcConfig.getSaltEncoding();

        final ModelNode addRealmOp = createEmptyOperation("add", pathAddress("subsystem", "elytron")
                .add("jdbc-realm", domainName + REALM_SUFFIX));
        ModelNode queryNode = new ModelNode();
        queryNode.get("sql").set(sqlQuery);
        queryNode.get("data-source").set(datasourceName);

        if (mapperType == JdbcConfig.MapperType.Plain) {
            final ModelNode mapperNode = new ModelNode();
            mapperNode.get("password-index").set(passwordIndex);

            queryNode.get("clear-password-mapper").set(mapperNode);
        }
        if (mapperType == JdbcConfig.MapperType.Digest) {
            final ModelNode mapperNode = new ModelNode();
            mapperNode.get("password-index").set(passwordIndex);
            mapperNode.get("algorithm").set(encodingAlgorithm);
            mapperNode.get("hash-encoding").set(hashEncoding);

            queryNode.get("simple-digest-mapper").set(mapperNode);
        }
        if (mapperType == JdbcConfig.MapperType.SaltedDigest) {
            final ModelNode mapperNode = new ModelNode();
            mapperNode.get("password-index").set(passwordIndex);
            mapperNode.get("salt-index").set(saltIndex);
            mapperNode.get("algorithm").set(encodingAlgorithm);
            mapperNode.get("hash-encoding").set(hashEncoding);
            mapperNode.get("salt-encoding").set(saltEncoding);

            queryNode.get("salted-simple-digest-mapper").set(mapperNode);
        }
        ModelNode attrMappingNode = new ModelNode();
        attrMappingNode.get("index").set(groupIndex);
        attrMappingNode.get("to").set("groups");
        queryNode.get("attribute-mapping").add(attrMappingNode);

        addRealmOp.get("principal-query").add(queryNode);

        ops.add(addRealmOp);

        ModelNode addSecurityDomainOp = new SecurityDomain().createSecurityDomain(new SecurityDomainModel(domainName, domainName + REALM_SUFFIX, true));
        ops.add(addSecurityDomainOp);

        return ops;
    }

}
