/*
 *
 * 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.qpid.client.transport;

import org.apache.qpid.client.HeartbeatListener;
import org.apache.qpid.transport.ConnectionHeartbeat;
import org.ietf.jgss.GSSContext;
import org.ietf.jgss.GSSException;
import org.ietf.jgss.GSSManager;
import org.ietf.jgss.GSSName;
import org.ietf.jgss.Oid;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.apache.qpid.client.security.AMQCallbackHandler;
import org.apache.qpid.client.security.CallbackHandlerRegistry;
import org.apache.qpid.jms.ConnectionURL;
import org.apache.qpid.transport.ClientDelegate;
import org.apache.qpid.transport.Connection;
import org.apache.qpid.transport.ConnectionException;
import org.apache.qpid.transport.ConnectionOpenOk;
import org.apache.qpid.transport.ConnectionSettings;
import org.apache.qpid.util.Strings;

import javax.security.sasl.Sasl;
import javax.security.sasl.SaslClient;
import javax.security.sasl.SaslException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *
 */
public class ClientConnectionDelegate extends ClientDelegate
{
    private static final Logger LOGGER = LoggerFactory.getLogger(ClientConnectionDelegate.class);

    private static final String KRB5_OID_STR = "1.2.840.113554.1.2.2";
    protected static final Oid KRB5_OID;

    static
    {
        Oid oid;
        try
        {
            oid = new Oid(KRB5_OID_STR);
        }
        catch (GSSException ignore)
        {
            oid = null;
        }

        KRB5_OID = oid;
    }

    private final ConnectionURL _connectionURL;
    private HeartbeatListener _heartbeatListener = HeartbeatListener.DEFAULT;

    /**
     * @param settings
     * @param connectionURL
     */
    public ClientConnectionDelegate(ConnectionSettings settings, ConnectionURL connectionURL)
    {
        super(settings);
        this._connectionURL = connectionURL;
    }

    @Override
    protected SaslClient createSaslClient(List<Object> brokerMechs) throws ConnectionException, SaslException
    {
        final String brokerMechanisms = Strings.join(" ", brokerMechs);
        final String restrictionList = getConnectionSettings().getSaslMechs();
        final String selectedMech = CallbackHandlerRegistry.getInstance().selectMechanism(brokerMechanisms, restrictionList);
        if (selectedMech == null)
        {
            throw new ConnectionException("Client and broker have no SASL mechanisms in common." +
                    " Broker allows : " + brokerMechanisms +
                    " Client has : " + CallbackHandlerRegistry.getInstance().getMechanisms()  +
                    " Client restricted itself to : " + (restrictionList != null ? restrictionList : "no restriction"));
        }

        if ((_connectionURL.getUsername() == null || _connectionURL.getPassword() == null)
                && CallbackHandlerRegistry.getInstance().isUserPassRequired(selectedMech))
        {
            throw new ConnectionException("Username and Password is required for the selected mechanism : " + selectedMech +
                    " Broker allows : " + brokerMechanisms +
                    " Client has : " + CallbackHandlerRegistry.getInstance().getMechanisms()  +
                    " Client restricted itself to : " + (restrictionList != null ? restrictionList : "no restriction"));
        }

        Map<String,Object> saslProps = new HashMap<String,Object>();
        if (getConnectionSettings().isUseSASLEncryption())
        {
            saslProps.put(Sasl.QOP, "auth-conf");
        }

        final AMQCallbackHandler handler = CallbackHandlerRegistry.getInstance().createCallbackHandler(selectedMech);
        handler.initialise(_connectionURL);
        final SaslClient sc = Sasl.createSaslClient(new String[] {selectedMech}, null, getConnectionSettings().getSaslProtocol(), getConnectionSettings().getSaslServerName(), saslProps, handler);

        return sc;
    }

    @Override
    public void connectionOpenOk(Connection conn, ConnectionOpenOk ok)
    {
        SaslClient sc = conn.getSaslClient();
        if (sc != null)
        {
            if (sc.getMechanismName().equals("GSSAPI"))
            {
                String id = getKerberosUser();
                if (id != null)
                {
                    conn.setUserID(id);
                }
            }
            else if (sc.getMechanismName().equals("EXTERNAL"))
            {
                if (conn.getSecurityLayer() != null)
                {
                    conn.setUserID(conn.getSecurityLayer().getUserID());
                }
            }
        }

        super.connectionOpenOk(conn, ok);
    }

    private String getKerberosUser()
    {
        LOGGER.debug("Obtaining userID from kerberos");
        String service = getConnectionSettings().getSaslProtocol() + "@" + getConnectionSettings().getSaslServerName();
        GSSManager manager = GSSManager.getInstance();

        try
        {
            GSSName acceptorName = manager.createName(service,
                GSSName.NT_HOSTBASED_SERVICE, KRB5_OID);

            GSSContext secCtx = manager.createContext(acceptorName,
                                                      KRB5_OID,
                                                      null,
                                                      GSSContext.INDEFINITE_LIFETIME);

            secCtx.initSecContext(new byte[0], 0, 1);

            if (secCtx.getSrcName() != null)
            {
                return secCtx.getSrcName().toString();
            }

        }
        catch (GSSException e)
        {
            LOGGER.warn("Unable to retrieve userID from Kerberos due to error",e);
        }

        return null;
    }

    @Override
    public void connectionHeartbeat(Connection conn, ConnectionHeartbeat heartbeat)
    {
        _heartbeatListener.heartbeatReceived();
    }


    public void setHeartbeatListener(HeartbeatListener listener)
    {
        _heartbeatListener = listener == null ? HeartbeatListener.DEFAULT : listener;
    }

    @Override
    public void writerIdle(final Connection connection)
    {
        super.writerIdle(connection);
        _heartbeatListener.heartbeatSent();
    }
}
