/*
 *  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.directory.server.kerberos.changepwd;


import java.io.IOException;

import javax.cache.Cache;

import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException;
import org.apache.directory.api.ldap.model.name.Dn;
import org.apache.directory.server.kerberos.ChangePasswordConfig;
import org.apache.directory.server.kerberos.changepwd.protocol.ChangePasswordProtocolHandler;
import org.apache.directory.server.kerberos.kdc.DirectoryPrincipalStore;
import org.apache.directory.server.kerberos.shared.replay.ReplayCache;
import org.apache.directory.server.kerberos.shared.replay.ReplayCacheImpl;
import org.apache.directory.server.kerberos.shared.replay.ReplayCacheImpl.ReplayCacheEntry;
import org.apache.directory.server.kerberos.shared.store.PrincipalStore;
import org.apache.directory.server.protocol.shared.DirectoryBackedService;
import org.apache.directory.server.protocol.shared.transport.TcpTransport;
import org.apache.directory.server.protocol.shared.transport.Transport;
import org.apache.directory.server.protocol.shared.transport.UdpTransport;
import org.apache.mina.core.service.IoAcceptor;
import org.apache.mina.transport.socket.DatagramSessionConfig;
import org.apache.mina.transport.socket.SocketAcceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * Contains the configuration parameters for the Change Password protocol provider.
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
public class ChangePasswordServer extends DirectoryBackedService
{
    /** logger for this class */
    private static final Logger LOG = LoggerFactory.getLogger( ChangePasswordServer.class );

    /** The default change password port. */
    private static final int DEFAULT_IP_PORT = 464;

    /** The default change password password policy for password length. */
    public static final int DEFAULT_PASSWORD_LENGTH = 6;

    /** The default change password password policy for category count. */
    public static final int DEFAULT_CATEGORY_COUNT = 3;

    /** The default change password password policy for token size. */
    public static final int DEFAULT_TOKEN_SIZE = 3;

    private ChangePasswordConfig config;

    /** the cache used for storing change password requests */
    private ReplayCache replayCache;


    /**
     * Creates a new instance of ChangePasswordConfiguration.
     */
    public ChangePasswordServer()
    {
        this( new ChangePasswordConfig() );
    }


    public ChangePasswordServer( ChangePasswordConfig config )
    {
        this.config = config;
    }


    /**
     * @throws IOException if we cannot bind to the specified ports
     */
    public void start() throws IOException, LdapInvalidDnException
    {
        PrincipalStore store = new DirectoryPrincipalStore( getDirectoryService(), new Dn( this.getSearchBaseDn() ) );

        LOG.debug( "initializing the changepassword replay cache" );

        Cache<String, ReplayCacheEntry> cache = getDirectoryService().getCacheService().getCache( "changePwdReplayCache",
            String.class, ReplayCacheEntry.class );
        replayCache = new ReplayCacheImpl( cache );

        for ( Transport transport : transports )
        {
            IoAcceptor acceptor = transport.getAcceptor();

            // Disable the disconnection of the clients on unbind
            acceptor.setCloseOnDeactivation( false );

            if ( transport instanceof UdpTransport )
            {
                // Allow the port to be reused even if the socket is in TIME_WAIT state
                ( ( DatagramSessionConfig ) acceptor.getSessionConfig() ).setReuseAddress( true );
            }
            else
            {
                // Allow the port to be reused even if the socket is in TIME_WAIT state
                ( ( SocketAcceptor ) acceptor ).setReuseAddress( true );

                // No Nagle's algorithm
                ( ( SocketAcceptor ) acceptor ).getSessionConfig().setTcpNoDelay( true );
            }

            // Set the handler
            acceptor.setHandler( new ChangePasswordProtocolHandler( this, store ) );

            // Bind
            acceptor.bind();
        }

        LOG.info( "ChangePassword service started." );
        //System.out.println( "ChangePassword service started." );
    }


    public void stop()
    {
        for ( Transport transport : getTransports() )
        {
            IoAcceptor acceptor = transport.getAcceptor();

            if ( acceptor != null )
            {
                acceptor.dispose();
            }
        }

        replayCache.clear();

        LOG.info( "ChangePassword service stopped." );
        //System.out.println( "ChangePassword service stopped." );
    }


    /**
     * @return the replayCache
     */
    public ReplayCache getReplayCache()
    {
        return replayCache;
    }


    public ChangePasswordConfig getConfig()
    {
        return config;
    }


    public int getTcpPort()
    {
        for ( Transport t : getTransports() )
        {
            if ( t instanceof TcpTransport )
            {
                return t.getPort();
            }
        }

        throw new IllegalStateException( "TCP transport is not enabled" );
    }


    /**
     * @see Object#toString()
     */
    public String toString()
    {
        StringBuilder sb = new StringBuilder();

        sb.append( "ChangePasswordServer[" ).append( getServiceName() ).append( "], listening on :" ).append( '\n' );

        if ( getTransports() != null )
        {
            for ( Transport transport : getTransports() )
            {
                sb.append( "    " ).append( transport ).append( '\n' );
            }
        }

        return sb.toString();
    }
}
