/*
 *  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.yoko.orb.OCI.IIOP;

import static org.apache.yoko.orb.OCI.IIOP.Exceptions.*;

import java.util.Arrays;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.apache.yoko.orb.OCI.ConnectCB;
import org.apache.yoko.orb.OCI.Connector;
import org.apache.yoko.orb.OCI.ProfileInfo;
import org.apache.yoko.orb.OCI.ProfileInfoHolder;
import org.omg.CORBA.Policy;
import org.omg.CSIIOP.TAG_CSI_SEC_MECH_LIST;
import org.omg.IOP.Codec;
import org.omg.IOP.IOR;
import org.omg.IOP.TaggedComponent;

final class Connector_impl extends org.omg.CORBA.LocalObject implements Connector {

    // the real logger backing instance.  We use the interface class as the locator
    static final Logger logger = Logger.getLogger(Connector.class.getName());

    private final IOR ior_;    // the target IOR we're connecting with

    private final Policy[] policies_;    // the policies used for the connection.

    private boolean keepAlive_; // The keepalive flag

    private final ConnectorInfo_impl info_; // Connector information

    private java.net.Socket socket_; // The socket

    private ListenerMap listenMap_;

    private final ConnectionHelper connectionHelper_;

    private byte[] transportInfo;

    private final ExtendedConnectionHelper extendedConnectionHelper_;

    private final Codec codec_;


    // ------------------------------------------------------------------
    // Private and protected functions
    // ------------------------------------------------------------------

    private void close() {
        logger.fine("Closing connection to host=" + this.info_.getHost() + ", port=" + this.info_.getPort());

        //
        // Close the socket
        //
        try {
            socket_.close();
            socket_ = null;
        } catch (java.io.IOException ex) {
            //ignore
        }
    }

    // ------------------------------------------------------------------
    // Standard IDL to Java Mapping
    // ------------------------------------------------------------------

    public String id() {
        return PLUGIN_ID.value;
    }

    public int tag() {
        return org.omg.IOP.TAG_INTERNET_IOP.value;
    }

    public org.apache.yoko.orb.OCI.Transport connect() {
        if (socket_ != null)
            close();

        //
        // Get the address
        //
        java.net.InetAddress address;
        try {
            address = java.net.InetAddress.getByName(this.info_.getHost());
        } catch (java.net.UnknownHostException ex) {
            logger.log(Level.FINE, "Host resolution error", ex);
            throw asCommFailure(ex);
        }


        //
        // Create socket and connect
        //
        try {
            logger.fine("Connecting to host=" + address + ", port=" + this.info_.getPort());
            if (connectionHelper_ != null) {
                socket_ = connectionHelper_.createSocket(ior_, policies_, address, this.info_.getPort());
            } else {
                socket_ = extendedConnectionHelper_.createSocket(ior_, policies_, address, this.info_.getPort());
            }
            logger.fine("Connection created with socket " + socket_);
        } catch (java.net.ConnectException ex) {
            logger.log(Level.FINE, "Error connecting to host=" + address + ", port=" + this.info_.getPort(), ex);
            throw new org.omg.CORBA.TRANSIENT(
                    org.apache.yoko.orb.OB.MinorCodes
                            .describeTransient(org.apache.yoko.orb.OB.MinorCodes.MinorConnectFailed)
                            + "Error connecting to host=" + address + ", port=" + this.info_.getPort() + ": " + ex.getMessage(),
                    org.apache.yoko.orb.OB.MinorCodes.MinorConnectFailed,
                    org.omg.CORBA.CompletionStatus.COMPLETED_NO);
        } catch (java.io.IOException ex) {
            logger.log(Level.FINE, "Error connecting to host=" + address + ", port=" + this.info_.getPort(), ex);
            throw (org.omg.CORBA.COMM_FAILURE)new org.omg.CORBA.COMM_FAILURE(
                    org.apache.yoko.orb.OB.MinorCodes
                            .describeCommFailure(org.apache.yoko.orb.OB.MinorCodes.MinorSocket)
                            + "Error connecting to host=" + address + ", port=" + this.info_.getPort() + ": " + ex.getMessage(),
                    org.apache.yoko.orb.OB.MinorCodes.MinorSocket,
                    org.omg.CORBA.CompletionStatus.COMPLETED_NO).initCause(ex);
        }

        //
        // Set TCP_NODELAY and SO_KEEPALIVE options
        //
        try {
            socket_.setTcpNoDelay(true);

            if (keepAlive_)
                socket_.setKeepAlive(true);
        } catch (java.net.SocketException ex) {
            logger.log(Level.FINE, "Socket setup error", ex);
            try {
                socket_.close();
            } catch (java.io.IOException e) {
            }
            throw Exceptions.asCommFailure(ex);
        }

        //
        // Create new transport
        //
        org.apache.yoko.orb.OCI.Transport tr = null;
        try {
            tr = new Transport_impl(socket_, listenMap_);
            socket_ = null;
        } catch (org.omg.CORBA.SystemException ex) {
            logger.log(Level.FINE, "Transport creation error", ex);
            try {
                socket_.close();
            } catch (java.io.IOException e) {
            }
            throw ex;
        }

        //
        // Call callbacks
        //
        org.apache.yoko.orb.OCI.TransportInfo trInfo = tr.get_info();
        try {
            info_._OB_callConnectCB(trInfo);
        } catch (org.omg.CORBA.SystemException ex) {
            logger.log(Level.FINE, "Connection callback error", ex);
            tr.close();
            throw ex;
        }

        //
        // Return new transport
        //
        return tr;
    }

    //
    // Helper class for connect_timeout()
    //
    private class ConnectTimeout extends Thread {
        private java.net.InetAddress address_ = null;

        private java.net.Socket so_ = null;

        private java.io.IOException ex_ = null;

        private boolean finished_ = false;

        private boolean timeout_ = false;

        ConnectTimeout(java.net.InetAddress address) {
            address_ = address;
        }

        public void run() {
            try {
                if (connectionHelper_ != null) {
                    so_ = connectionHelper_.createSocket(ior_, policies_, address_, Connector_impl.this.info_.getPort());
                } else {
                    so_ = extendedConnectionHelper_.createSocket(ior_, policies_, address_, Connector_impl.this.info_.getPort());
                }
            } catch (java.io.IOException ex) {
                logger.log(Level.FINE, "Socket creation error", ex);
                ex_ = ex;
            }

            synchronized (this) {
                if (timeout_) {
                    if (so_ != null) {
                        try {
                            so_.close();
                        } catch (java.io.IOException ex) {
                        }

                        so_ = null;
                    }
                } else {
                    finished_ = true;
                    ConnectTimeout.this.notify();
                }
            }
        }

        synchronized java.net.Socket waitForConnect(int t)
                throws java.io.IOException {
            while (!finished_) {
                try {
                    ConnectTimeout.this.wait(t);
                } catch (InterruptedException ex) {
                    continue;
                }

                if (!finished_) // Timeout
                {
                    timeout_ = true;
                    return null;
                }
            }

            if (so_ != null) // Connect succeeded
                return so_;

            if (ex_ != null) // Connect failed
                throw ex_;

            throw new InternalError();
        }
    }

    public org.apache.yoko.orb.OCI.Transport connect_timeout(int t) {
        if (socket_ != null)
            close();

        //
        // Get the address
        //
        java.net.InetAddress address = null;
        try {
            address = java.net.InetAddress.getByName(this.info_.getHost());
        } catch (java.net.UnknownHostException ex) {
            logger.log(Level.FINE, "Host resolution error", ex);
            throw asCommFailure(ex);
        }

        //
        // Create socket and connect
        //
        try {
            ConnectTimeout connectTimeout = new ConnectTimeout(address);
            connectTimeout.start();

            socket_ = connectTimeout.waitForConnect(t);

            if (socket_ == null)
                return null;
        } catch (java.net.ConnectException ex) {
            logger.log(Level.FINE, "Socket connection error", ex);
            throw new org.omg.CORBA.TRANSIENT(
                    org.apache.yoko.orb.OB.MinorCodes
                            .describeTransient(org.apache.yoko.orb.OB.MinorCodes.MinorConnectFailed)
                            + ": " + ex.getMessage(),
                    org.apache.yoko.orb.OB.MinorCodes.MinorConnectFailed,
                    org.omg.CORBA.CompletionStatus.COMPLETED_NO);
        } catch (java.io.IOException ex) {
            logger.log(Level.FINE, "Socket I/O error", ex);
            throw (org.omg.CORBA.COMM_FAILURE)new org.omg.CORBA.COMM_FAILURE(
                    org.apache.yoko.orb.OB.MinorCodes
                            .describeCommFailure(org.apache.yoko.orb.OB.MinorCodes.MinorSocket)
                            + ": " + ex.getMessage(),
                    org.apache.yoko.orb.OB.MinorCodes.MinorSocket,
                    org.omg.CORBA.CompletionStatus.COMPLETED_NO).initCause(ex);
        }

        //
        // Set TCP_NODELAY and SO_KEEPALIVE options
        //
        try {
            socket_.setTcpNoDelay(true);

            if (keepAlive_)
                socket_.setKeepAlive(true);
        } catch (java.net.SocketException ex) {
            logger.log(Level.FINE, "Socket setup error", ex);
            try {
                socket_.close();
            } catch (java.io.IOException e) {
            }
            throw Exceptions.asCommFailure(ex);
        }

        //
        // Create new transport
        //
        org.apache.yoko.orb.OCI.Transport tr = null;
        try {
            tr = new Transport_impl(socket_, listenMap_);
            socket_ = null;
        } catch (org.omg.CORBA.SystemException ex) {
            logger.log(Level.FINE, "Transport setup error", ex);
            try {
                socket_.close();
            } catch (java.io.IOException e) {
            }
            throw ex;
        }

        //
        // Call callbacks
        //
        org.apache.yoko.orb.OCI.TransportInfo trInfo = tr.get_info();
        try {
            info_._OB_callConnectCB(trInfo);
        } catch (org.omg.CORBA.SystemException ex) {
            logger.log(Level.FINE, "Callback setup error", ex);
            tr.close();
            throw ex;
        }

        //
        // Return new transport
        //
        return tr;
    }

    public org.apache.yoko.orb.OCI.ProfileInfo[] get_usable_profiles(
            org.omg.IOP.IOR ior, org.omg.CORBA.Policy[] policies) {
        //
        // Make sure that the set of policies is met
        //
        for (int i = 0; i < policies.length; i++) {
            if (policies[i].policy_type() == org.apache.yoko.orb.OB.PROTOCOL_POLICY_ID.value) {
                org.apache.yoko.orb.OB.ProtocolPolicy protocolPolicy = org.apache.yoko.orb.OB.ProtocolPolicyHelper
                        .narrow(policies[i]);
                if (!protocolPolicy.contains(PLUGIN_ID.value))
                    return new org.apache.yoko.orb.OCI.ProfileInfo[0];
            }
        }

        org.apache.yoko.orb.OCI.ProfileInfoSeqHolder profileInfoSeq = new org.apache.yoko.orb.OCI.ProfileInfoSeqHolder();
        profileInfoSeq.value = new org.apache.yoko.orb.OCI.ProfileInfo[0];
        Util.extractAllProfileInfos(ior, profileInfoSeq, true, this.info_.getHost(), this.info_.getPort(),
                false, codec_);

        //check that the transport info matches ours.
        //we could return just the profiles that match rather than bailing if one doesn't match.
        for (int i = 0; i< profileInfoSeq.value.length; i++ ) {
            TaggedComponent[] components = profileInfoSeq.value[i].components;
            byte[] otherTransportInfo = new byte[0];
            for (int j = 0; j < components.length; j++ ) {
                TaggedComponent component = components[j];
                if (component.tag == TAG_CSI_SEC_MECH_LIST.value) {
                    otherTransportInfo = component.component_data;
                    break;
                }
            }
            if (!Arrays.equals(transportInfo, otherTransportInfo)) {
                return new org.apache.yoko.orb.OCI.ProfileInfo[0];
            }
        }
        return profileInfoSeq.value;
    }

    public boolean equal(org.apache.yoko.orb.OCI.Connector con) {
        Connector_impl impl = null;
        try {
            impl = (Connector_impl) con;
        } catch (ClassCastException ex) {
            return false;
        }

        //
        // Compare ports
        //
        if (this.info_.getPort() != impl.info_.getPort())
            return false;

        //
        // Direct host name comparison
        //
        if (!this.info_.getHost().equals(impl.info_.getHost())) {
            //
            // Direct host name comparision failed - must look up
            // addresses to be really sure if the hosts differ
            //
            try {
                java.net.InetAddress addr1 = java.net.InetAddress
                        .getByName(this.info_.getHost());

                java.net.InetAddress addr2 = java.net.InetAddress
                        .getByName(impl.info_.getHost());

                if (!addr1.equals(addr2))
                    return false;
            } catch (java.net.UnknownHostException ex) {
                //
                // Return false on hostname lookup failure
                //
                return false;
            }
        }

        return Arrays.equals(transportInfo, impl.transportInfo);
    }

    byte[] extractTransportInfo(IOR ior) {
        ProfileInfoHolder holder = new ProfileInfoHolder();
        // we need to extract the profile information from the IOR to see if this connection has
        // any transport-level security defined.
        if (org.apache.yoko.orb.OCI.IIOP.Util.extractProfileInfo(ior, holder)) {
            ProfileInfo profileInfo = holder.value;
            for (int i = 0; i < profileInfo.components.length; i++) {
                // we're lookoing for the security mechanism items.
                if (profileInfo.components[i].tag == TAG_CSI_SEC_MECH_LIST.value) {
                    return profileInfo.components[i].component_data;
                }
            }
        }
        return new byte[0];
    }

    public org.apache.yoko.orb.OCI.ConnectorInfo get_info() {
        return info_;
    }

    // ------------------------------------------------------------------
    // Yoko internal functions
    // Application programs must not use these functions directly
    // ------------------------------------------------------------------

    private Connector_impl(IOR ior, Policy[] policies, String host, int port, boolean keepAlive, ConnectCB[] cb, ListenerMap lm, ConnectionHelper helper, ExtendedConnectionHelper xhelper, Codec codec) {
        ior_ = ior;
        policies_ = policies;
        keepAlive_ = keepAlive;
        info_ = new ConnectorInfo_impl(host, port, cb);
        listenMap_ = lm;
        connectionHelper_ = helper;
        extendedConnectionHelper_ = xhelper;
        codec_ = codec;
        transportInfo = extractTransportInfo(ior);
    }

    public Connector_impl(IOR ior, Policy[] policies, String host, int port, boolean keepAlive, ConnectCB[] cb, ListenerMap lm, ConnectionHelper helper, Codec codec) {
        this(ior, policies, host, port, keepAlive, cb, lm, helper, null, codec);
    }

    public Connector_impl(IOR ior, Policy[] policies, String host, int port, boolean keepAlive, ConnectCB[] cb, ListenerMap lm, ExtendedConnectionHelper helper, Codec codec) {
        this(ior, policies, host, port, keepAlive, cb, lm, null, helper, codec);
    }

    public void finalize() throws Throwable {
        if (socket_ != null)
            close();

        super.finalize();
    }
}
