/*
 *  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.jni;

import java.io.InputStream;
import java.util.Properties;

/** Echo server example
 *
 * @author Mladen Turk
 * @version $Revision$, $Date$
 */

public class Echo {

    public static String echoEcho = null;
    public static String echoAddr = null;
    public static int echoPort    = 0;
    public static int echoNmax    = 0;
    public static int echoNrun    = 0;
    public static long echoPool   = 0;

    private static Poller echoPoller     = null;
    private static Acceptor echoAcceptor = null;

    private static Object threadLock = new Object();

    static {

        try {
            InputStream is = Echo.class.getResourceAsStream
                ("/org/apache/tomcat/jni/Echo.properties");
            Properties props = new Properties();
            props.load(is);
            is.close();
            echoAddr = props.getProperty("echo.ip", "127.0.0.1");
            echoPort = Integer.decode(props.getProperty("echo.port", "23")).intValue();
            echoNmax = Integer.decode(props.getProperty("echo.max", "1")).intValue();
        }
        catch (Throwable t) {
            ; // Nothing
        }
    }

    /* Acceptor thread. Listens for new connections */
    private class Acceptor extends java.lang.Thread {
        private long serverSock = 0;
        private long inetAddress = 0;
        private long pool = 0;
        public Acceptor() throws Exception {
            try {

                pool = Pool.create(Echo.echoPool);
                System.out.println("Accepting: " +  Echo.echoAddr + ":" +
                                   Echo.echoPort);
                inetAddress = Address.info(Echo.echoAddr, Socket.APR_INET,
                                           Echo.echoPort, 0,
                                           pool);
                serverSock = Socket.create(Socket.APR_INET, Socket.SOCK_STREAM,
                                           Socket.APR_PROTO_TCP, pool);
                long sa = Address.get(Socket.APR_LOCAL, serverSock);
                Sockaddr addr = new Sockaddr();
                if (Address.fill(addr, sa)) {
                    System.out.println("Host: " + addr.hostname);
                    System.out.println("Server: " + addr.servname);
                    System.out.println("IP: " + Address.getip(sa) +
                                       ":" + addr.port);
                }
                int rc = Socket.bind(serverSock, inetAddress);
                if (rc != 0) {
                  throw(new Exception("Can't create Acceptor: bind: " + Error.strerror(rc)));
                }
                Socket.listen(serverSock, 5);
            }
            catch( Exception ex ) {
                ex.printStackTrace();
                throw(new Exception("Can't create Acceptor"));
            }
        }

        public void run() {
            int i = 0;
            try {
                while (true) {
                    long clientSock = Socket.accept(serverSock);
                    System.out.println("Accepted id: " +  i);

                    try {
                        long sa = Address.get(Socket.APR_REMOTE, clientSock);
                        Sockaddr raddr = new Sockaddr();
                        if (Address.fill(raddr, sa)) {
                            System.out.println("Remote Host: " + Address.getnameinfo(sa, 0));
                            System.out.println("Remote IP: " + Address.getip(sa) +
                                               ":" + raddr.port);
                        }
                        sa = Address.get(Socket.APR_LOCAL, clientSock);
                        Sockaddr laddr = new Sockaddr();
                        if (Address.fill(laddr, sa)) {
                            System.out.println("Local Host: " + laddr.hostname);
                            System.out.println("Local Server: " + Address.getnameinfo(sa, 0));
                            System.out.println("Local IP: " + Address.getip(sa) +
                                               ":" + laddr.port);
                        }

                    } catch (Exception e) {
                        // Ignore
                        e.printStackTrace();
                    }

                    Socket.timeoutSet(clientSock, 10000000);
                    Worker worker = new Worker(clientSock, i++,
                                               this.getClass().getName());
                    Echo.incThreads();
                    worker.start();
                }
            }
            catch( Exception ex ) {
                ex.printStackTrace();
            }
        }
    }

    /* Poller thread. Listens for new recycled connections */
    private class Poller extends java.lang.Thread {
        private long serverPollset = 0;
        private long pool = 0;
        private int nsocks = 0;
        public Poller() {
            try {

                pool = Pool.create(Echo.echoPool);
                serverPollset = Poll.create(16, pool, 0, 10000000);
            }
            catch( Exception ex ) {
                ex.printStackTrace();
            }
        }

        public void add(long socket) {
            int rv = Poll.add(serverPollset, socket,
                              Poll.APR_POLLIN);
            if (rv == Status.APR_SUCCESS) {
                System.out.println("Added worker to pollset");
                nsocks++;
            }
        }

        public void remove(long socket) {
            int rv = Poll.remove(serverPollset, socket);
            if (rv == Status.APR_SUCCESS) {
               nsocks--;
               System.out.println("Removed worker from pollset");
            }
            else {
               System.out.println("Failed removing worker from pollset");
            }
        }

        public void run() {
            while (true) {
                try {
                    if (nsocks < 1) {
                        java.lang.Thread.sleep(1);
                        continue;
                    }
                    /* Two times size then  created pollset */
                    long [] desc = new long[64];
                    /* USe 1 second poll timeout */
                    int rv = Poll.poll(serverPollset, 1000000, desc, false);
                    if (rv > 0) {
                        for (int n = 0; n < rv; n++) {
                            long clientSock = desc[n*2+1];
                            System.out.println("Poll flags " + desc[n*2]);
                            remove(clientSock);
                            Worker worker = new Worker(clientSock, n,
                                                       this.getClass().getName());
                            Echo.incThreads();
                            worker.start();
                        }
                    }
                    else {
                        if (Status.APR_STATUS_IS_TIMEUP(-rv))
                            System.out.println("Timeup");
                        else {
                            System.out.println("Error " + (-rv));
                        }
                    }
                }
                /* XXX: JFC quick hack
                catch(Error err ) {
                    if (Status.APR_STATUS_IS_TIMEUP(err.getError())) {
                        /0 TODO: deal with timeout 0/
                    }
                    else {
                        err.printStackTrace();
                        break;
                    }
                }
                 */
                catch( Exception ex ) {
                    ex.printStackTrace();
                    break;
                }
            }
        }
    }

    private class Worker extends java.lang.Thread {
        private int workerId = 0;
        private long clientSock = 0;
        private byte [] wellcomeMsg = null;
        public Worker(long clientSocket, int workerId, String from) {
            this.clientSock = clientSocket;
            this.workerId = workerId;
            wellcomeMsg = ("Echo server id: " + this.workerId + " from " +
                           from + "\r\n").getBytes();
        }

        public void run() {
            boolean doClose = false;
            try {
                Socket.send(clientSock, wellcomeMsg, 0, wellcomeMsg.length);
                /* Do a blocking read byte at a time */
                byte [] buf = new byte[1];
                while (Socket.recv(clientSock, buf, 0, 1) == 1) {
                    if (buf[0] == '\n')
                        break;
                    else if (buf[0] == '!') {
                        doClose = true;
                        break;
                    }
                }
                if (doClose) {
                    try {
                        byte [] msg = ("Bye from worker: " + workerId + "\r\n").getBytes();
                        Socket.send(clientSock, msg, 0, msg.length);
                    } catch(Exception e) { }

                    Socket.close(clientSock);
                }
                else {
                    try {
                        byte [] msg = ("Recycling worker: " + workerId + "\r\n").getBytes();
                        Socket.send(clientSock, msg, 0, msg.length);
                    } catch(Exception e) { }
                    /* Put the socket to the keep-alive poll */
                    Echo.echoPoller.add(clientSock);
                }
            } catch (Exception e) {
                Socket.close(clientSock);
                e.printStackTrace();
            }
            Echo.decThreads();
            System.out.println("Worker: " +  workerId + " finished");
        }
    }

    public Echo()
    {
        echoPool = Pool.create(0);
        try {
            echoAcceptor = new Acceptor();
            echoAcceptor.start();
            echoPoller = new Poller();
            echoPoller.start();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public static void incThreads() {
        synchronized(threadLock) {
            echoNrun++;
        }
    }

    public static void decThreads() {
        synchronized(threadLock) {
            echoNrun--;
        }
    }

    public static void main(String [] args) {
        try {
            Library.initialize(null);
            long [] inf = new long[16];
            System.out.println("Info ...");
            System.out.println("  Native        " + Library.versionString());
            System.out.println("  APR           " + Library.aprVersionString());
            OS.info(inf);
            System.out.println("OS Info ...");
            System.out.println("  Physical      " + inf[0]);
            System.out.println("  Avail         " + inf[1]);
            System.out.println("  Swap          " + inf[2]);
            System.out.println("  Swap free     " + inf[3]);
            System.out.println("  Shared        " + inf[4]);
            System.out.println("  Buffers size  " + inf[5]);
            System.out.println("  Load          " + inf[6]);

            System.out.println("  Idle          " + inf[7]);
            System.out.println("  Kernel        " + inf[8]);
            System.out.println("  User          " + inf[9]);

            System.out.println("  Proc creation " + inf[10]);
            System.out.println("  Proc kernel   " + inf[11]);
            System.out.println("  Proc user     " + inf[12]);
            System.out.println("  Curr working  " + inf[13]);
            System.out.println("  Peak working  " + inf[14]);
            System.out.println("  Page faults   " + inf[15]);

            SSL.initialize(null);
            System.out.println("OpenSSL ...");
            System.out.println("  version       " + SSL.versionString());
            System.out.println("  number        " + SSL.version());

            System.out.println("Starting Native Echo server example on port " +
                               echoAddr + ":" + echoPort);
            Echo echo = new Echo();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}
