/**
 * 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
 *
 *      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.apache.camel.component.springldap;

import java.util.Map;
import java.util.function.BiFunction;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import javax.naming.directory.ModificationItem;

import org.apache.camel.Exchange;
import org.apache.camel.impl.DefaultProducer;
import org.apache.commons.lang.StringUtils;
import org.springframework.ldap.core.AttributesMapper;
import org.springframework.ldap.core.ContextSource;
import org.springframework.ldap.core.LdapOperations;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.core.support.BaseLdapPathContextSource;
import org.springframework.ldap.query.LdapQueryBuilder;

public class SpringLdapProducer extends DefaultProducer {

    public static final String DN = "dn";
    public static final String FILTER = "filter";
    public static final String ATTRIBUTES = "attributes";
    public static final String PASSWORD = "password";
    public static final String MODIFICATION_ITEMS = "modificationItems";

    public static final String FUNCTION = "function";
    public static final String REQUEST = "request";

    SpringLdapEndpoint endpoint;

    private AttributesMapper<Object> mapper = new AttributesMapper<Object>() {

        @Override
        public Object mapFromAttributes(Attributes attributes) throws NamingException {
            return attributes;
        }
    };

    /**
     * Initializes the SpringLdapProducer with the given endpoint
     */
    public SpringLdapProducer(SpringLdapEndpoint endpoint) {
        super(endpoint);
        this.endpoint = endpoint;
    }

    /**
     * Performs the LDAP operation defined in SpringLdapEndpoint that created
     * this producer. The in-message in the exchange must be a map, containing
     * the following entries:
     * 
     * <pre>
     * key: "dn" - base DN for the LDAP operation
     * key: "filter" - necessary for the search operation only; LDAP filter for the search operation,
     * see <a http://en.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol>http://en.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol</a>
     * key: "attributes" - necessary for the bind operation only; an instance of javax.naming.directory.Attributes,
     * containing the information necessary to create an LDAP node.
     * key: "password" - necessary for the authentication operation only;
     * key: "modificationItems" - necessary for the modify_attributes operation only;
     * key: "function" - necessary for the function_driven operation only; provides a flexible hook into the {@link LdapTemplate} to call any method
     * key: "request" - necessary for the function_driven operation only; passed into the "function" to enable the client to bind parameters that need to be passed into the {@link LdapTemplate}
     * </pre>
     * 
     * The keys are defined as final fields above.
     */
    @Override
    public void process(Exchange exchange) throws Exception {
        @SuppressWarnings("unchecked")
        Map<String, Object> body = exchange.getIn().getBody(Map.class);

        LdapOperation operation = endpoint.getOperation();
        if (null == operation) {
            throw new UnsupportedOperationException("LDAP operation must not be empty, but you provided an empty operation");
        }

        LdapTemplate ldapTemplate = endpoint.getLdapTemplate();

        String dn = (String)body.get(DN);
        if (StringUtils.isBlank(dn)) {
            ContextSource contextSource = ldapTemplate.getContextSource();
            if (contextSource instanceof BaseLdapPathContextSource) {
                dn = ((BaseLdapPathContextSource) contextSource).getBaseLdapPathAsString();
            }
        }
        if (operation != LdapOperation.FUNCTION_DRIVEN && (StringUtils.isBlank(dn))) {
            throw new UnsupportedOperationException("DN must not be empty, but you provided an empty DN");
        }

        switch (operation) {
        case SEARCH:
            String filter = (String)body.get(FILTER);
            exchange.getIn().setBody(ldapTemplate.search(dn, filter, endpoint.scopeValue(), mapper));
            break;
        case BIND:
            Attributes attributes = (Attributes)body.get(ATTRIBUTES);
            ldapTemplate.bind(dn, null, attributes);
            break;
        case UNBIND:
            ldapTemplate.unbind(dn);
            break;
        case AUTHENTICATE:
            ldapTemplate.authenticate(LdapQueryBuilder.query().base(dn).filter((String)body.get(FILTER)), (String)body.get(PASSWORD));
            break;
        case MODIFY_ATTRIBUTES:
            ModificationItem[] modificationItems = (ModificationItem[])body.get(MODIFICATION_ITEMS);
            ldapTemplate.modifyAttributes(dn, modificationItems);
            break;
        case FUNCTION_DRIVEN:
            BiFunction<LdapOperations, Object, ?> ldapOperationFunction = (BiFunction<LdapOperations, Object, ?>)body.get(FUNCTION);
            Object ldapOperationRequest = body.get(REQUEST);
            exchange.getIn().setBody(ldapOperationFunction.apply(ldapTemplate, ldapOperationRequest));
            break;
        default:
            throw new UnsupportedOperationException("Bug in the Spring-LDAP component. Despite of all assertions, you managed to call an unsupported operation '" + operation
                                                    + "'");
        }
    }
}
