/*
 * 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.tomcat.util.net;

import java.io.File;
import java.net.InetAddress;
import java.net.ServerSocket;

import org.junit.Assert;
import org.junit.Test;

import org.apache.catalina.connector.Connector;
import org.apache.catalina.startup.Tomcat;
import org.apache.catalina.startup.TomcatBaseTest;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.jni.Address;
import org.apache.tomcat.jni.Error;
import org.apache.tomcat.jni.Library;
import org.apache.tomcat.jni.OS;
import org.apache.tomcat.jni.Pool;
import org.apache.tomcat.jni.Socket;

/**
 * Test case for the Endpoint implementations. The testing framework will ensure
 * that each implementation is tested.
 */
public class TestXxxEndpoint extends TomcatBaseTest {

    private static Log log = LogFactory.getLog(TestXxxEndpoint.class);

    private long createAprPool() {

        // Create the pool for the server socket
        try {
            return Pool.create(0);
        } catch (UnsatisfiedLinkError e) {
            log.error("Could not create socket pool", e);
            return 0;
        }
    }

    private long createAprSocket(int port, long pool)
                 throws Exception {
        /**
         * Server socket "pointer".
         */
        long serverSock = 0;

        String address = InetAddress.getByName("localhost").getHostAddress();

        // Create the APR address that will be bound
        int family = Socket.APR_INET;
        if (Library.APR_HAVE_IPV6) {
            if (!OS.IS_BSD && !OS.IS_WIN32 && !OS.IS_WIN64)
                family = Socket.APR_UNSPEC;
         }

        long inetAddress = 0;
        try {
            inetAddress = Address.info(address, family,
                                       port, 0, pool);
            // Create the APR server socket
            serverSock = Socket.create(Address.getInfo(inetAddress).family,
                                       Socket.SOCK_STREAM,
                                       Socket.APR_PROTO_TCP, pool);
        } catch (Exception ex) {
            log.error("Could not create socket for address '" + address + "'");
            return 0;
        }

        if (OS.IS_UNIX) {
            Socket.optSet(serverSock, Socket.APR_SO_REUSEADDR, 1);
        }
        // Deal with the firewalls that tend to drop the inactive sockets
        Socket.optSet(serverSock, Socket.APR_SO_KEEPALIVE, 1);
        // Bind the server socket
        int ret = Socket.bind(serverSock, inetAddress);
        if (ret != 0) {
            log.error("Could not bind: " + Error.strerror(ret));
            throw (new Exception(Error.strerror(ret)));
        }
        return serverSock;
    }

    private void destroyAprSocket(long serverSock, long pool) {
        if (serverSock != 0) {
            Socket.shutdown(serverSock, Socket.APR_SHUTDOWN_READWRITE);
            Socket.close(serverSock);
            Socket.destroy(serverSock);
        }

        if (pool != 0) {
            Pool.destroy(pool);
            pool = 0;
        }
    }

    @Test
    public void testStartStopBindOnInit() throws Exception {
        Tomcat tomcat = getTomcatInstance();
        File appDir = new File(getBuildDirectory(), "webapps/examples");
        tomcat.addWebapp(null, "/examples", appDir.getAbsolutePath());

        tomcat.start();

        int port = getPort();

        tomcat.getConnector().stop();
        Exception e = null;
        ServerSocket s = null;
        long pool = 0;
        long nativeSocket = 0;
        boolean isApr = tomcat.getConnector().getProtocolHandlerClassName().contains("Apr");
        try {
            // This should throw an Exception
            if (isApr) {
                pool = createAprPool();
                Assert.assertTrue(pool != 0);
                nativeSocket = createAprSocket(port, pool);
                Assert.assertTrue(nativeSocket != 0);
            } else {
                s = new ServerSocket(port, 100,
                        InetAddress.getByName("localhost"));
            }
        } catch (Exception e1) {
            e = e1;
        } finally {
            try {
                if (isApr) {
                    destroyAprSocket(nativeSocket, pool);
                } else if (s != null) {
                    s.close();
                }
            } catch (Exception e2) { /* Ignore */ }
        }
        if (e != null) {
            log.info("Exception was", e);
        }
        Assert.assertNotNull(e);
        tomcat.getConnector().start();
    }

    @Test
    public void testStartStopBindOnStart() throws Exception {
        Tomcat tomcat = getTomcatInstance();
        Connector c = tomcat.getConnector();
        c.setProperty("bindOnInit", "false");

        File appDir = new File(getBuildDirectory(), "webapps/examples");
        tomcat.addWebapp(null, "/examples", appDir.getAbsolutePath());


        tomcat.start();
        int port = getPort();

        tomcat.getConnector().stop();
        Exception e = null;
        ServerSocket s = null;
        long pool = 0;
        long nativeSocket = 0;
        boolean isApr = tomcat.getConnector().getProtocolHandlerClassName().contains("Apr");
        try {
            // This should not throw an Exception
            if (isApr) {
                pool = createAprPool();
                Assert.assertTrue(pool != 0);
                nativeSocket = createAprSocket(port, pool);
                Assert.assertTrue(nativeSocket != 0);
            } else {
                s = new ServerSocket(port, 100,
                        InetAddress.getByName("localhost"));
            }
        } catch (Exception e1) {
            e = e1;
        } finally {
            try {
                if (isApr) {
                    destroyAprSocket(nativeSocket, pool);
                } else if (s != null) {
                    s.close();
                }
            } catch (Exception e2) { /* Ignore */ }
        }
        Assert.assertNull(e);
        tomcat.getConnector().start();
    }
}
