/*
 *  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 org.apache.yoko.orb.CORBA.InputStream;
import org.apache.yoko.orb.CORBA.OutputStream;
import org.omg.CORBA.Any;
import org.omg.CSIIOP.CompoundSecMechList;
import org.omg.CSIIOP.CompoundSecMechListHelper;
import org.omg.CSIIOP.TAG_TLS_SEC_TRANS;
import org.omg.CSIIOP.TLS_SEC_TRANS;
import org.omg.CSIIOP.TLS_SEC_TRANSHelper;
import org.omg.CSIIOP.TransportAddress;
import org.omg.IOP.Codec;
import org.omg.IOP.CodecPackage.FormatMismatch;
import org.omg.IOP.CodecPackage.TypeMismatch;

final public class Util {
    static public org.omg.IOP.IOR createIOR(String host, int port, String id,
            org.apache.yoko.orb.OCI.ProfileInfo profileInfo) {
        org.omg.IOP.IOR ior = new org.omg.IOP.IOR();
        ior.type_id = id;
        ior.profiles = new org.omg.IOP.TaggedProfile[1];
        ior.profiles[0] = new org.omg.IOP.TaggedProfile();
        ior.profiles[0].tag = org.omg.IOP.TAG_INTERNET_IOP.value;

        if (profileInfo.major == 1 && profileInfo.minor == 0) {
            org.omg.IIOP.ProfileBody_1_0 body = new org.omg.IIOP.ProfileBody_1_0();
            body.iiop_version = new org.omg.IIOP.Version((byte) 1, (byte) 0);
            body.host = host;
            if (port >= 0x8000)
                body.port = (short) (port - 0xffff - 1);
            else
                body.port = (short) port;
            body.object_key = profileInfo.key;
            org.apache.yoko.orb.OCI.Buffer buf = new org.apache.yoko.orb.OCI.Buffer();
            OutputStream out = new OutputStream(buf);
            out._OB_writeEndian();
            org.omg.IIOP.ProfileBody_1_0Helper.write(out, body);
            ior.profiles[0].profile_data = new byte[buf.length()];
            System.arraycopy(buf.data(), 0, ior.profiles[0].profile_data, 0,
                    buf.length());
        } else {
            org.omg.IIOP.ProfileBody_1_1 body = new org.omg.IIOP.ProfileBody_1_1();
            body.iiop_version = new org.omg.IIOP.Version(profileInfo.major,
                    profileInfo.minor);
            body.host = host;
            if (port >= 0x8000)
                body.port = (short) (port - 0xffff - 1);
            else
                body.port = (short) port;
            body.object_key = profileInfo.key;
            body.components = profileInfo.components;
            org.apache.yoko.orb.OCI.Buffer buf = new org.apache.yoko.orb.OCI.Buffer();
            OutputStream out = new OutputStream(buf);
            out._OB_writeEndian();
            org.omg.IIOP.ProfileBody_1_1Helper.write(out, body);
            ior.profiles[0].profile_data = new byte[buf.length()];
            System.arraycopy(buf.data(), 0, ior.profiles[0].profile_data, 0,
                    buf.length());
        }

        return ior;
    }

    static public org.omg.IOP.IOR createIOR(org.omg.IOP.IOR ior, String id,
            byte[] key) {
        //
        // Extract the IIOP profile information from the provided IOR
        //
        int profile;
        for (profile = 0; profile < ior.profiles.length; profile++)
            if (ior.profiles[profile].tag == org.omg.IOP.TAG_INTERNET_IOP.value)
                break;

        // TODO: Internal error?
        org.apache.yoko.orb.OB.Assert._OB_assert(profile < ior.profiles.length);

        org.apache.yoko.orb.OCI.Buffer buf = new org.apache.yoko.orb.OCI.Buffer(
                ior.profiles[profile].profile_data,
                ior.profiles[profile].profile_data.length);
        InputStream in = new InputStream(buf, 0, false, null, null);
        in._OB_readEndian();
        org.omg.IIOP.ProfileBody_1_0 body = org.omg.IIOP.ProfileBody_1_0Helper
                .read(in);

        org.apache.yoko.orb.OCI.ProfileInfo profileInfo = new org.apache.yoko.orb.OCI.ProfileInfo();
        profileInfo.key = key;
        profileInfo.major = body.iiop_version.major;
        profileInfo.minor = body.iiop_version.minor;
        profileInfo.components = new org.omg.IOP.TaggedComponent[0];
        return createIOR(body.host, body.port, id, profileInfo);
    }

    static public boolean extractProfileInfo(org.omg.IOP.IOR ior,
            org.apache.yoko.orb.OCI.ProfileInfoHolder profileInfo) {
        org.apache.yoko.orb.OCI.ProfileInfoSeqHolder profileInfoSeq = new org.apache.yoko.orb.OCI.ProfileInfoSeqHolder();
        profileInfoSeq.value = new org.apache.yoko.orb.OCI.ProfileInfo[0];
        extractAllProfileInfos(ior, profileInfoSeq, false, null, 0, false, null);
        if (profileInfoSeq.value.length > 0) {
            profileInfo.value = profileInfoSeq.value[0];
            return true;
        }

        return false;
    }

    static public boolean hostMatch(String host1, String host2,
            boolean loopbackMatches) {
        //
        // Direct host name comparison
        //
        if (!host1.equals(host2)) {
            //
            //
            // 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(host1);

                java.net.InetAddress addr2 = java.net.InetAddress
                        .getByName(host2);

                if (!addr1.equals(addr2)) {
                    //
                    // Address comparison failed - shall I extract
                    // the key if the profile body contains the
                    // loopback address?
                    //
                    if (loopbackMatches) {
                        java.net.InetAddress loopback = java.net.InetAddress
                                .getByName("127.0.0.1");

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

        return true;
    }

    static public void extractAllProfileInfos(org.omg.IOP.IOR ior,
            org.apache.yoko.orb.OCI.ProfileInfoSeqHolder profileInfoSeq,
            boolean performMatch, String host, int port, boolean loopbackMatches, Codec codec) {
        short portNo;
        if (port >= 0x8000) {
            portNo = (short) (port - 0xffff - 1);
        }
        else {
            portNo = (short) port;
        }

        java.util.Vector vec = new java.util.Vector();
        for (int i = 0; i < ior.profiles.length; i++) {
            if (ior.profiles[i].tag == org.omg.IOP.TAG_INTERNET_IOP.value) {
                //
                // Get the IIOP profile body
                //
                byte[] data = ior.profiles[i].profile_data;
                org.apache.yoko.orb.OCI.Buffer buf = new org.apache.yoko.orb.OCI.Buffer(
                        data, data.length);
                InputStream in = new InputStream(buf, 0, false, null, null);
                in._OB_readEndian();
                org.omg.IIOP.ProfileBody_1_0 body = org.omg.IIOP.ProfileBody_1_0Helper
                        .read(in);

                //
                // Read components if the IIOP version is > 1.0
                //
                org.omg.IOP.TaggedComponent[] components;
                if (body.iiop_version.major > 1 || body.iiop_version.minor > 0) {
                    int len = in.read_ulong();
                    components = new org.omg.IOP.TaggedComponent[len];
                    for (int j = 0; j < len; j++) {
                        components[j] = org.omg.IOP.TaggedComponentHelper.read(in);
                    }
                } else {
                    components = new org.omg.IOP.TaggedComponent[0];
                }

                if (performMatch) {
                    //
                    // Check primary host/port
                    //
                    boolean match = false;
                    if (portNo == body.port
                            && hostMatch(host, body.host, loopbackMatches)) {
                        match = true;
                    }

                    //
                    // Check alternate host/port
                    //
                    if (!match) {
                        for (int j = 0; j < components.length && !match; j++) {
                            if (components[j].tag == org.omg.IOP.TAG_ALTERNATE_IIOP_ADDRESS.value) {
                                byte[] d = components[j].component_data;
                                org.apache.yoko.orb.OCI.Buffer b = new org.apache.yoko.orb.OCI.Buffer(
                                        d, d.length);
                                InputStream s = new InputStream(b, 0, false,
                                        null, null);
                                s._OB_readEndian();
                                String altHost = s.read_string();
                                short altPort = s.read_ushort();
                                if (portNo == altPort
                                        && hostMatch(host, altHost,
                                                loopbackMatches)) {
                                    match = true;
                                }
                            } else if (components[j].tag == org.omg.CSIIOP.TAG_CSI_SEC_MECH_LIST.value) {
                                Any any;
                                try {
                                    any = codec.decode_value(components[j].component_data, CompoundSecMechListHelper.type());
                                    CompoundSecMechList csml = CompoundSecMechListHelper.extract(any);

                                    for (int k = 0; i < csml.mechanism_list.length && !match; i++) {
                                        org.omg.IOP.TaggedComponent tc = csml.mechanism_list[k].transport_mech;
                                        if (tc.tag == TAG_TLS_SEC_TRANS.value) {
                                            Any tstAny = codec.decode_value(tc.component_data, TLS_SEC_TRANSHelper.type());
                                            TLS_SEC_TRANS tst = TLS_SEC_TRANSHelper.extract(tstAny);
                                            TransportAddress[] transportAddresses = tst.addresses;
                                            for (TransportAddress addr: transportAddresses) {
                                                if (portNo == addr.port && hostMatch(host, addr.host_name, loopbackMatches)) {
                                                    match = true;
                                                    break;
                                                }
                                            }

                                        }
                                    }

                                } catch (FormatMismatch e) {
                                } catch (TypeMismatch e) {
                                }
                            }
                        }
                    }

                    if (!match)
                        continue;
                }

                //
                // OK, found a match
                //
                org.apache.yoko.orb.OCI.ProfileInfo profileInfo = new org.apache.yoko.orb.OCI.ProfileInfo();
                profileInfo.key = body.object_key;
                profileInfo.minor = body.iiop_version.minor;
                profileInfo.major = body.iiop_version.major;
                profileInfo.id = ior.profiles[i].tag;
                profileInfo.index = i;
                profileInfo.components = components;

                vec.addElement(profileInfo);
            }
        }

        if (vec.size() > 0) {
            int len = profileInfoSeq.value.length;
            if (len == 0) {
                profileInfoSeq.value = new org.apache.yoko.orb.OCI.ProfileInfo[vec
                        .size()];
                vec.copyInto(profileInfoSeq.value);
            } else {
                org.apache.yoko.orb.OCI.ProfileInfo[] arr = new org.apache.yoko.orb.OCI.ProfileInfo[len
                        + vec.size()];
                System.arraycopy(profileInfoSeq.value, 0, arr, 0, len);
                for (int i = 0; i < vec.size(); i++) {
                    arr[len + i] = (org.apache.yoko.orb.OCI.ProfileInfo) vec.elementAt(i);
                }
                profileInfoSeq.value = arr;
            }
        }
    }

    static public boolean equivalent(org.omg.IOP.IOR ior1, org.omg.IOP.IOR ior2) {
        int p1, p2, b1, b2;
        int cnt1 = 0, cnt2 = 0;
        org.omg.IIOP.ProfileBody_1_0[] bodies1;
        org.omg.IIOP.ProfileBody_1_0[] bodies2;

        //
        // Calculate number of IIOP profiles in ior1
        //
        for (p1 = 0; p1 < ior1.profiles.length; p1++)
            if (ior1.profiles[p1].tag == org.omg.IOP.TAG_INTERNET_IOP.value)
                cnt1++;

        //
        // Calculate number of IIOP profiles in ior2
        //
        for (p2 = 0; p2 < ior2.profiles.length; p2++)
            if (ior2.profiles[p2].tag == org.omg.IOP.TAG_INTERNET_IOP.value)
                cnt2++;

        //
        // Return false now if the number of IIOP profile bodies do not
        // match
        //
        if (cnt1 != cnt2)
            return false;

        //
        // Create an array with all IIOP profile bodies of ior1
        //
        bodies1 = new org.omg.IIOP.ProfileBody_1_0[cnt1];
        for (p1 = 0, b1 = 0; p1 < ior1.profiles.length; p1++)
            if (ior1.profiles[p1].tag == org.omg.IOP.TAG_INTERNET_IOP.value) {
                byte[] data = ior1.profiles[p1].profile_data;
                org.apache.yoko.orb.OCI.Buffer buf = new org.apache.yoko.orb.OCI.Buffer(
                        data, data.length);
                InputStream in = new InputStream(buf, 0, false, null, null);
                in._OB_readEndian();
                bodies1[b1++] = org.omg.IIOP.ProfileBody_1_0Helper.read(in);
            }

        if (b1 != cnt1)
            throw new InternalError();

        //
        // Create an array with all IIOP profile bodies of ior2
        //
        bodies2 = new org.omg.IIOP.ProfileBody_1_0[cnt2];
        for (p2 = 0, b2 = 0; p2 < ior2.profiles.length; p2++)
            if (ior2.profiles[p2].tag == org.omg.IOP.TAG_INTERNET_IOP.value) {
                byte[] data = ior2.profiles[p2].profile_data;
                org.apache.yoko.orb.OCI.Buffer buf = new org.apache.yoko.orb.OCI.Buffer(
                        data, data.length);
                InputStream in = new InputStream(buf, 0, false, null, null);
                in._OB_readEndian();
                bodies2[b2++] = org.omg.IIOP.ProfileBody_1_0Helper.read(in);
            }

        if (b2 != cnt2)
            throw new InternalError();

        //
        // Check for profile body matches
        //
        for (b1 = 0; b1 < cnt1; b1++) {
            for (b2 = 0; b2 < cnt2; b2++) {
                if (bodies2[b2] == null)
                    continue;

                //
                // Compare profile bodies
                //
                if (compareBodies(bodies1[b1], bodies2[b2])) {
                    //
                    // OK, found a match
                    //
                    bodies1[b1] = null;
                    bodies2[b2] = null;
                    break;
                }
            }
        }

        //
        // Check whether there are any unmatched IIOP profile bodies
        //
        for (b1 = 0; b1 < cnt1; b1++)
            if (bodies1[b1] != null)
                return false;

        for (b2 = 0; b2 < cnt2; b2++)
            if (bodies2[b2] != null)
                return false;

        return true;
    }

    static boolean compareBodies(org.omg.IIOP.ProfileBody_1_0 body1,
            org.omg.IIOP.ProfileBody_1_0 body2) {
        //
        // Compare versions
        //
        if (body1.iiop_version.major != body2.iiop_version.major
                || body1.iiop_version.minor != body2.iiop_version.minor)
            return false;

        //
        // Compare ports
        //
        if (body1.port != body2.port)
            return false;

        //
        // Compare object keys
        //
        if (body1.object_key.length != body2.object_key.length)
            return false;

        int k;
        for (k = 0; k < body1.object_key.length; k++)
            if (body1.object_key[k] != body2.object_key[k])
                return false;

        //
        // Direct host name comparison
        //
        if (!body1.host.equals(body2.host)) {
            //
            // 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(body1.host);

                java.net.InetAddress addr2 = java.net.InetAddress
                        .getByName(body2.host);

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

        //
        // OK, found a match
        //
        return true;
    }

    //
    // Calculate a hash for an IOR containing IIOP profiles
    //
    static public int hash(org.omg.IOP.IOR ior, int maximum) {
        int hash = 0;

        for (int i = 0; i < ior.profiles.length; i++) {
            if (ior.profiles[i].tag == org.omg.IOP.TAG_INTERNET_IOP.value) {
                //
                // Get the first IIOP profile body
                //
                byte[] data = ior.profiles[i].profile_data;
                org.apache.yoko.orb.OCI.Buffer buf = new org.apache.yoko.orb.OCI.Buffer(
                        data, data.length);
                InputStream in = new InputStream(buf, 0, false, null, null);
                in._OB_readEndian();
                org.omg.IIOP.ProfileBody_1_0 body = org.omg.IIOP.ProfileBody_1_0Helper
                        .read(in);

                //
                // Add port to hash
                //
                hash ^= body.port;

                //
                // Add object key to hash
                //
                for (int j = 0; j + 1 < body.object_key.length; j += 2)
                    hash ^= body.object_key[j + 1] * 256 + body.object_key[j];
            }
        }

        return hash % (maximum + 1);
    }
}
