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

import java.util.concurrent.ExecutorService;
import java.util.logging.Level;

final class GIOPServerStarterThreaded extends GIOPServerStarter {
    //
    // The starter thread
    //
    protected final class Starter implements Runnable {

        public void run() {
            try {
                starterRun();
            } catch (RuntimeException ex) {
                Assert._OB_assert(ex);
            }

            logger.fine("Shutting down ORB server listener thread"); 
            //
            // Shutdown the acceptor so that no further connections are
            // accepted
            //
            logCloseAcceptor();
            acceptor_.shutdown();

            //
            // Accept all connections which might have queued up in the
            // listen() backlog
            while (true) {
                org.apache.yoko.orb.OCI.Transport transport = null;

                try {
                    transport = acceptor_.accept(false);
                } catch (org.omg.CORBA.SystemException ex) {
                }

                if (transport == null) {
                    logger.fine("Null transport received from a connect"); 
                    break;
                }

                try {
                    GIOPConnection connection = new GIOPConnectionThreaded(
                            orbInstance_, transport,
                            oaInterface_);

                    connection.setState(GIOPConnection.State.Closing);
                } catch (org.omg.CORBA.SystemException ex) {
                    // Ignore SystemExceptions
                }
            }

            //
            // Close the acceptor
            //
            acceptor_.close();

        }
    }

    // ----------------------------------------------------------------------
    // GIOPServerStarterThreaded package member implementation
    // ----------------------------------------------------------------------

    GIOPServerStarterThreaded(ORBInstance orbInstance,
            org.apache.yoko.orb.OCI.Acceptor acceptor, OAInterface oaInterface) {
        super(orbInstance, acceptor, oaInterface);

        logger.fine("GIOPServer thread started " + this + " using acceptor " + acceptor); 
        try {
            //
            // Retrieve the thread group for the servers
            //
            ExecutorService executor = orbInstance_.getServerExecutor();

            //
            // Start starter thread
            //
            executor.submit(new Starter());
        } catch (OutOfMemoryError ex) {
            acceptor_.close();
            state_ = StateClosed;
            throw new org.omg.CORBA.IMP_LIMIT(org.apache.yoko.orb.OB.MinorCodes
                    .describeImpLimit(org.apache.yoko.orb.OB.MinorCodes.MinorThreadLimit),
                    org.apache.yoko.orb.OB.MinorCodes.MinorThreadLimit,
                    org.omg.CORBA.CompletionStatus.COMPLETED_NO);
        }
    }

    // ----------------------------------------------------------------------
    // GIOPServerStarterThreaded public member implementation
    // ----------------------------------------------------------------------

    //
    // Change the state of the worker
    //
    synchronized public void setState(int state) {
        //
        // Don't do anything if there is no state change
        //
        if (state_ == state) {
            return;
        }
        
        logger.fine("Setting server state to " + state); 

        //
        // It is not possible to transition backwards, except if we are
        // in holding state
        //
        if (state_ != StateHolding && state < state_) {
            return;
        }

        switch (state) {
        case StateActive: {
            for (int i = 0; i < connections_.size(); i++) {
                GIOPConnection w = (GIOPConnection) connections_.elementAt(i);
                w.setState(GIOPConnection.State.Active);
            }

            break;
        }

        case StateHolding:
            for (int i = 0; i < connections_.size(); i++) {
                GIOPConnection w = (GIOPConnection) connections_.elementAt(i);
                w.setState(GIOPConnection.State.Holding);
            }
            break;

        case StateClosed: {
            for (int i = 0; i < connections_.size(); i++) {
                GIOPConnection w = (GIOPConnection) connections_.elementAt(i);
                w.setState(GIOPConnection.State.Closing);
            }
            connections_.removeAllElements();

            //
            // Connect to this starter's acceptor, to unblock the call
            // to accept() in the starter thread
            //
            try {
                org.apache.yoko.orb.OCI.Transport tr = acceptor_.connect_self();
                tr.close();
            } catch (org.omg.CORBA.SystemException ex) {
                //
                // Ignore all system exceptions
                //
            }

            break;
        }
        }

        //
        // Update the state and notify about the state change
        //
        state_ = state;
        notifyAll();
    }

    //
    // Run method for starter thread
    //
    public void starterRun() {
        while (true) {
            //
            // Get new transport, blocking
            //
            org.apache.yoko.orb.OCI.Transport transport = null;
            try {
                transport = acceptor_.accept(true);
                Assert._OB_assert(transport != null);
            } catch (org.omg.CORBA.NO_PERMISSION ex) {
                //
                // Ignore NO_PERMISSION exceptions
                //
            } catch (org.omg.CORBA.SystemException ex) {
                //
                // Ignore exception. This probably means that the server
                // exceeded the number of available file descriptors.
                //
            }

            synchronized (this) {
                //
                // Reap the existing set of workers
                //
                reapWorkers();

                //
                // Check whether we are on hold
                //
                while (state_ == StateHolding) {
                    try {
                        logger.fine("Waiting on an inbound connection because the state is holding.  acceptor=" + acceptor_); 
                        wait();
                    } catch (InterruptedException ex) {
                    }
                }

                logger.fine("Processing an inbound connection with state=" + state_); 
                if (transport != null) {
                    try {
                        if (state_ == StateActive) {
                            //
                            // If we're active, we create and add a new
                            // worker to the worker list
                            //
                            GIOPConnection connection = new GIOPConnectionThreaded(
                                    orbInstance_, transport, oaInterface_);
                            connections_.addElement(connection);
                            connection.setState(GIOPConnection.State.Active);
                        } else {
                            logger.fine("Processing an inbound connection because state is closed"); 
                            //
                            // If we're closed, we create a new dummy
                            // worker, only in order to set it to
                            // StateClosing for proper connection shutdown
                            //
                            Assert._OB_assert(state_ == StateClosed);
                            logger.fine("Processing an inbound connection because state is closed"); 
                            GIOPConnection connection = new GIOPConnectionThreaded(
                                    orbInstance_, transport, oaInterface_);
                            logger.fine("Created connection " + connection); 

                            connection.setState(GIOPConnection.State.Closing);
                            logger.fine("set connection state to closing"); 
                        }
                    } catch (org.omg.CORBA.SystemException ex) {
                        String msg = "can't accept connection\n" + ex.getMessage();
                        logger.log(java.util.logging.Level.WARNING, msg, ex);
                    }
                }

                if (state_ == StateClosed) {
                    logger.fine("Shutting down server thread"); 
                    break;
                }
            }
        }
    }
}
