/**
 * $RCSfile$
 * $Revision$
 * $Date$
 *
 * Copyright 2003-2007 Jive Software.
 *
 * All rights reserved. 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.jivesoftware.smack.sasl;

import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.SASLAuthentication;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.util.StringUtils;

import java.io.IOException;
import java.util.Map;
import java.util.HashMap;
import org.apache.harmony.javax.security.auth.callback.CallbackHandler;
import org.apache.harmony.javax.security.auth.callback.UnsupportedCallbackException;
import org.apache.harmony.javax.security.auth.callback.Callback;
import org.apache.harmony.javax.security.auth.callback.NameCallback;
import org.apache.harmony.javax.security.auth.callback.PasswordCallback;
import org.apache.harmony.javax.security.sasl.RealmCallback;
import org.apache.harmony.javax.security.sasl.RealmChoiceCallback;
import de.measite.smack.Sasl;
import org.apache.harmony.javax.security.sasl.SaslClient;
import org.apache.harmony.javax.security.sasl.SaslException;

/**
 * Base class for SASL mechanisms. Subclasses must implement these methods:
 * <ul>
 *  <li>{@link #getName()} -- returns the common name of the SASL mechanism.</li>
 * </ul>
 * Subclasses will likely want to implement their own versions of these mthods:
 *  <li>{@link #authenticate(String, String, String)} -- Initiate authentication stanza using the
 *  deprecated method.</li>
 *  <li>{@link #authenticate(String, String, CallbackHandler)} -- Initiate authentication stanza
 *  using the CallbackHandler method.</li>
 *  <li>{@link #challengeReceived(String)} -- Handle a challenge from the server.</li>
 * </ul>
 *
 * @author Jay Kline
 */
public abstract class SASLMechanism implements CallbackHandler {

    private SASLAuthentication saslAuthentication;
    protected SaslClient sc;
    protected String authenticationId;
    protected String password;
    protected String hostname;


    public SASLMechanism(SASLAuthentication saslAuthentication) {
        this.saslAuthentication = saslAuthentication;
    }

    /**
     * Builds and sends the <tt>auth</tt> stanza to the server. Note that this method of
     * authentication is not recommended, since it is very inflexable.  Use
     * {@link #authenticate(String, String, CallbackHandler)} whenever possible.
     *
     * @param username the username of the user being authenticated.
     * @param host     the hostname where the user account resides.
     * @param password the password for this account.
     * @throws IOException If a network error occurs while authenticating.
     * @throws XMPPException If a protocol error occurs or the user is not authenticated.
     */
    public void authenticate(String username, String host, String password) throws IOException, XMPPException {
        //Since we were not provided with a CallbackHandler, we will use our own with the given
        //information

        //Set the authenticationID as the username, since they must be the same in this case.
        this.authenticationId = username;
        this.password = password;
        this.hostname = host;

        String[] mechanisms = { getName() };
        Map<String,String> props = new HashMap<String,String>();
        sc = Sasl.createSaslClient(mechanisms, username, "xmpp", host, props, this);
        authenticate();
    }

    /**
     * Builds and sends the <tt>auth</tt> stanza to the server. The callback handler will handle
     * any additional information, such as the authentication ID or realm, if it is needed.
     *
     * @param username the username of the user being authenticated.
     * @param host     the hostname where the user account resides.
     * @param cbh      the CallbackHandler to obtain user information.
     * @throws IOException If a network error occures while authenticating.
     * @throws XMPPException If a protocol error occurs or the user is not authenticated.
     */
    public void authenticate(String username, String host, CallbackHandler cbh) throws IOException, XMPPException {
        String[] mechanisms = { getName() };
        Map<String,String> props = new HashMap<String,String>();
        sc = Sasl.createSaslClient(mechanisms, username, "xmpp", host, props, cbh);
        authenticate();
    }

    protected void authenticate() throws IOException, XMPPException {
        String authenticationText = null;
        try {
            if(sc.hasInitialResponse()) {
                byte[] response = sc.evaluateChallenge(new byte[0]);
                authenticationText = StringUtils.encodeBase64(response, false);
            }
        } catch (SaslException e) {
            throw new XMPPException("SASL authentication failed", e);
        }

        // Send the authentication to the server
        getSASLAuthentication().send(new AuthMechanism(getName(), authenticationText));
    }


    /**
     * The server is challenging the SASL mechanism for the stanza he just sent. Send a
     * response to the server's challenge.
     *
     * @param challenge a base64 encoded string representing the challenge.
     * @throws IOException if an exception sending the response occurs.
     */
    public void challengeReceived(String challenge) throws IOException {
        byte response[];
        if(challenge != null) {
            response = sc.evaluateChallenge(StringUtils.decodeBase64(challenge));
        } else {
            response = sc.evaluateChallenge(new byte[0]);
        }

        Packet responseStanza;
        if (response == null) {
            responseStanza = new Response();
        }
        else {
            responseStanza = new Response(StringUtils.encodeBase64(response, false));
        }

        // Send the authentication to the server
        getSASLAuthentication().send(responseStanza);
    }

    /**
     * Returns the common name of the SASL mechanism. E.g.: PLAIN, DIGEST-MD5 or GSSAPI.
     *
     * @return the common name of the SASL mechanism.
     */
    protected abstract String getName();


    protected SASLAuthentication getSASLAuthentication() {
        return saslAuthentication;
    }

    /**
     * 
     */
    public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
        for (int i = 0; i < callbacks.length; i++) {
            if (callbacks[i] instanceof NameCallback) {
                NameCallback ncb = (NameCallback)callbacks[i];
                ncb.setName(authenticationId);
            } else if(callbacks[i] instanceof PasswordCallback) {
                PasswordCallback pcb = (PasswordCallback)callbacks[i];
                pcb.setPassword(password.toCharArray());
            } else if(callbacks[i] instanceof RealmCallback) {
                RealmCallback rcb = (RealmCallback)callbacks[i];
                rcb.setText(hostname);
            } else if(callbacks[i] instanceof RealmChoiceCallback){
                //unused
                //RealmChoiceCallback rccb = (RealmChoiceCallback)callbacks[i];
            } else {
               throw new UnsupportedCallbackException(callbacks[i]);
            }
         }
    }

    /**
     * Initiating SASL authentication by select a mechanism.
     */
    public class AuthMechanism extends Packet {
        final private String name;
        final private String authenticationText;

        public AuthMechanism(String name, String authenticationText) {
            if (name == null) {
                throw new NullPointerException("SASL mechanism name shouldn't be null.");
            }
            this.name = name;
            this.authenticationText = authenticationText;
        }

        public String toXML() {
            StringBuilder stanza = new StringBuilder();
            stanza.append("<auth mechanism=\"").append(name);
            stanza.append("\" xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">");
            if (authenticationText != null &&
                    authenticationText.trim().length() > 0) {
                stanza.append(authenticationText);
            }
            stanza.append("</auth>");
            return stanza.toString();
        }
    }

    /**
     * A SASL challenge stanza.
     */
    public static class Challenge extends Packet {
        final private String data;

        public Challenge(String data) {
            this.data = data;
        }

        public String toXML() {
            StringBuilder stanza = new StringBuilder();
            stanza.append("<challenge xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">");
            if (data != null &&
                    data.trim().length() > 0) {
                stanza.append(data);
            }
            stanza.append("</challenge>");
            return stanza.toString();
        }
    }

    /**
     * A SASL response stanza.
     */
    public class Response extends Packet {
        final private String authenticationText;

        public Response() {
            authenticationText = null;
        }

        public Response(String authenticationText) {
            if (authenticationText == null || authenticationText.trim().length() == 0) {
                this.authenticationText = null;
            }
            else {
                this.authenticationText = authenticationText;
            }
        }

        public String toXML() {
            StringBuilder stanza = new StringBuilder();
            stanza.append("<response xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">");
            if (authenticationText != null) {
                stanza.append(authenticationText);
            }
            stanza.append("</response>");
            return stanza.toString();
        }
    }

    /**
     * A SASL success stanza.
     */
    public static class Success extends Packet {
        final private String data;

        public Success(String data) {
            this.data = data;
        }

        public String toXML() {
            StringBuilder stanza = new StringBuilder();
            stanza.append("<success xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">");
            if (data != null &&
                    data.trim().length() > 0) {
                stanza.append(data);
            }
            stanza.append("</success>");
            return stanza.toString();
        }
    }

    /**
     * A SASL failure stanza.
     */
    public static class Failure extends Packet {
        final private String condition;

        public Failure(String condition) {
            this.condition = condition;
        }

        /**
         * Get the SASL related error condition.
         * 
         * @return the SASL related error condition.
         */
        public String getCondition() {
            return condition;
        }

        public String toXML() {
            StringBuilder stanza = new StringBuilder();
            stanza.append("<failure xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">");
            if (condition != null &&
                    condition.trim().length() > 0) {
                stanza.append("<").append(condition).append("/>");
            }
            stanza.append("</failure>");
            return stanza.toString();
        }
    }
}
