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

import java.io.IOException;
import java.util.Properties;

import javax.management.MBeanRegistration;
import javax.management.MBeanServer;
import javax.management.Notification;
import javax.management.NotificationListener;
import javax.management.ObjectName;

import org.apache.commons.modeler.Registry;

/**
 *
 * @author Costin Manolache
 */
public class JkHandler implements MBeanRegistration, NotificationListener {
    public static final int OK=0;
    public static final int LAST=1;
    public static final int ERROR=2;

    protected Properties properties=new Properties();
    protected WorkerEnv wEnv;
    protected JkHandler next;
    protected String nextName=null;
    protected String name;
    protected int id;

    // XXX Will be replaced with notes and (configurable) ids
    // Each represents a 'chain' - similar with ActionCode in Coyote ( the concepts
    // will be merged ).    
    public static final int HANDLE_RECEIVE_PACKET   = 10;
    public static final int HANDLE_SEND_PACKET      = 11;
    public static final int HANDLE_FLUSH            = 12;
    public static final int HANDLE_THREAD_END       = 13;
    
    public void setWorkerEnv( WorkerEnv we ) {
        this.wEnv=we;
    }

    /** Set the name of the handler. Will allways be called by
     *  worker env after creating the worker.
     */
    public void setName(String s ) {
        name=s;
    }

    public String getName() {
        return name;
    }

    /** Set the id of the worker. We use an id for faster dispatch.
     *  Since we expect a decent number of handler in system, the
     *  id is unique - that means we may have to allocate bigger
     *  dispatch tables. ( easy to fix if needed )
     */
    public void setId( int id ) {
        this.id=id;
    }

    public int getId() {
        return id;
    }
    
    /** Catalina-style "recursive" invocation.
     *  A chain is used for Apache/3.3 style iterative invocation.
     */
    public void setNext( JkHandler h ) {
        next=h;
    }

    public void setNext( String s ) {
        nextName=s;
    }

    public String getNext() {
        if( nextName==null ) {
            if( next!=null)
                nextName=next.getName();
        }
        return nextName;
    }

    /** Should register the request types it can handle,
     *   same style as apache2.
     */
    public void init() throws IOException {
    }

    /** Clean up and stop the handler
     */
    public void destroy() throws IOException {
    }

     public MsgContext createMsgContext() {
         return new MsgContext(8*1024);
     }

     public MsgContext createMsgContext(int bsize) {
        return new MsgContext(bsize);
     }
 
    public int invoke(Msg msg, MsgContext mc )  throws IOException {
        return OK;
    }
    
    public void setProperty( String name, String value ) {
        properties.put( name, value );
    }

    public String getProperty( String name ) {
        return properties.getProperty(name) ;
    }

    /** Experimental, will be replaced. This allows handlers to be
     *  notified when other handlers are added.
     */
    public void addHandlerCallback( JkHandler w ) {

    }

    public void handleNotification(Notification notification, Object handback)
    {
//        BaseNotification bNot=(BaseNotification)notification;
//        int code=bNot.getCode();
//
//        MsgContext ctx=(MsgContext)bNot.getSource();


    }

    protected String domain;
    protected ObjectName oname;
    protected MBeanServer mserver;

    public ObjectName getObjectName() {
        return oname;
    }

    public String getDomain() {
        return domain;
    }

    public ObjectName preRegister(MBeanServer server,
                                  ObjectName oname) throws Exception {
        this.oname=oname;
        mserver=server;
        domain=oname.getDomain();
        if( name==null ) {
            name=oname.getKeyProperty("name");
        }
        
        // we need to create a workerEnv or set one.
        ObjectName wEnvName=new ObjectName(domain + ":type=JkWorkerEnv");
        if ( wEnv == null ) {
            wEnv=new WorkerEnv();
        }
        if( ! mserver.isRegistered(wEnvName )) {
            Registry.getRegistry(null, null).registerComponent(wEnv, wEnvName, null);
        }
        mserver.invoke( wEnvName, "addHandler", 
                new Object[] {name, this}, 
                new String[] {"java.lang.String", 
                              "org.apache.jk.core.JkHandler"});
        return oname;
    }
    
    public void postRegister(Boolean registrationDone) {
    }

    public void preDeregister() throws Exception {
    }

    public void postDeregister() {
    }

    public void pause() throws Exception {
    }

    public void resume() throws Exception {
    }

}
