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


import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import org.apache.directory.mitosis.common.CSN;
import org.apache.directory.mitosis.common.CSNFactory;
import org.apache.directory.mitosis.common.Replica;
import org.apache.directory.mitosis.common.ReplicaId;
import org.apache.directory.mitosis.common.DefaultCSNFactory;
import org.apache.directory.mitosis.common.DefaultUUIDFactory;
import org.apache.directory.mitosis.common.UUID;
import org.apache.directory.mitosis.common.UUIDFactory;
import org.apache.directory.mitosis.service.ReplicationInterceptor;
import org.apache.directory.mitosis.store.ReplicationStore;
import org.apache.directory.mitosis.store.derby.DerbyReplicationStore;
import org.apache.directory.shared.ldap.util.StringTools;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A configuration for {@link ReplicationInterceptor}.  This configuration can be
 * used by calling {@link ReplicationInterceptor#setConfiguration(ReplicationConfiguration)}.
 * 
 * @org.apache.xbean.XBean
 *
 * @author The Apache Directory Project Team
 */
public class ReplicationConfiguration
{
    public static final int DEFAULT_LOG_MAX_AGE = 7;
    public static final int DEFAULT_REPLICATION_INTERVAL = 5;
    public static final int DEFAULT_RESPONSE_TIMEOUT = 60;
    public static final int DEFAULT_SERVER_PORT = 7846;

    /** The logger */
    private static Logger log = LoggerFactory.getLogger( ReplicationConfiguration.class );

    /** The server identifier */ 
    private ReplicaId replicaId;
    
    /** Default values for the communication part */
    private int serverPort = DEFAULT_SERVER_PORT;
    private int responseTimeout = DEFAULT_RESPONSE_TIMEOUT;
    private int replicationInterval = DEFAULT_REPLICATION_INTERVAL;

    /** List of connected replicas */
    private final Set<Replica> peerReplicas = new HashSet<Replica>();
    
    /** Factories */
    private UUIDFactory uuidFactory = new DefaultUUIDFactory();
    private CSNFactory csnFactory = new DefaultCSNFactory();
    private ReplicationStore store = new DerbyReplicationStore();
    
    /** The longest period of time before a stored entry is removed from storage */
    private int logMaxAge = DEFAULT_LOG_MAX_AGE; // a week (days)


    /**
     * Creates a new instance with default properties except for
     * the {@link ReplicaId} of the service and the  the list of peer
     * {@link Replica}s.  You can set these properties by calling
     * {@link #setReplicaId(ReplicaId)} and {@link #setPeerReplicas(Set)}
     * respectively.
     */
    public ReplicationConfiguration()
    {
    }

    /**
     * Returns the TCP/IP port number that a {@link ReplicationInterceptor}
     * listens to.  The default value is {@link #DEFAULT_SERVER_PORT}. 
     */
    public int getServerPort()
    {
        return serverPort;
    }


    /**
     * Sets the TCP/IP port number that a {@link ReplicationInterceptor}
     * listens to.  The default value is {@link #DEFAULT_SERVER_PORT}.
     */
    public void setServerPort( int serverPort )
    {
        this.serverPort = serverPort;
    }

    /**
     * Returns the response timeout value (seconds) for each sent message
     * during the communication between replicas.  If any response message
     * is not received within this timeout, the connection is closed and
     * reestablished.  The default value is {@link #DEFAULT_RESPONSE_TIMEOUT}.
     */
    public int getResponseTimeout()
    {
        return responseTimeout;
    }

    /**
     * Sets the response timeout value (seconds) for each sent message
     * during the communication between replicas.  If any response message
     * is not received within this timeout, the connection is closed and
     * reestablished.  The default value is {@link #DEFAULT_RESPONSE_TIMEOUT}.
     */
    public void setResponseTimeout( int responseTimeout )
    {
        this.responseTimeout = responseTimeout;
    }

    /**
     * Returns the replication data exchange interval (seconds) between two
     * replicas. The default value is {@link #DEFAULT_REPLICATION_INTERVAL}.
     * 
     * @return <tt>0</tt> if automatic replication is disabled
     */
    public int getReplicationInterval() {
        return replicationInterval;
    }


    /**
     * Sets the replication data exchange interval (seconds) between two
     * replicas. The default value is {@link #DEFAULT_REPLICATION_INTERVAL}.
     * 
     * @param replicationInterval <tt>0</tt> or below to disable automatic replication.
     */
    public void setReplicationInterval( int replicationInterval )
    {
        if( replicationInterval < 0 )
        {
            replicationInterval = 0;
        }
        this.replicationInterval = replicationInterval;
    }


    /**
     * Returns the {@link CSNFactory} for generating {@link CSN}s.
     * The default factory is {@link DefaultCSNFactory}.
     */
    public CSNFactory getCsnFactory()
    {
        return csnFactory;
    }


    /**
     * Sets the {@link CSNFactory} for generating {@link CSN}s.
     * The default factory is {@link DefaultCSNFactory}.
     */
    public void setCsnFactory( CSNFactory csnFactory )
    {
        this.csnFactory = csnFactory;
    }

    /**
     * Adds the specified {@link Replica} to the remote peer replica list.
     */
    public void addPeerReplica( Replica peer )
    {
        assert peer != null;
        peerReplicas.add( peer );
    }

    /**
     * Removed the specified {@link Replica} from the remote peer replica list.
     */
    public void removePeerReplica( Replica peer )
    {
        assert peer != null;
        peerReplicas.remove( peer );
    }

    /**
     * Clears the remote peer replica list.
     */
    public void removeAllPeerReplicas()
    {
        peerReplicas.clear();
    }

    /**
     * Returns the remote peer replica list.
     */
    public Set<Replica> getPeerReplicas()
    {
        Set<Replica> result = new HashSet<Replica>();
        result.addAll( peerReplicas );
        return result;
    }


    /**
     * Sets the remote peer replica list.
     */
    public void setPeerReplicas( Set replicas )
    {
        assert replicas != null;

        Set<Replica> normalizedReplicas = new HashSet<Replica>();
        Iterator i = replicas.iterator();
        
        while ( i.hasNext() )
        {
            Object o = i.next();
            
            if ( o instanceof Replica )
            {
                normalizedReplicas.add( ( Replica ) o );
            }
            else
            {
                normalizedReplicas.add( new Replica( o.toString() ) );
            }
        }
        
        peerReplicas.clear();
        peerReplicas.addAll( normalizedReplicas );
    }

    /**
     * Returns the ID of the replica this configuration is configuring.
     */
    public ReplicaId getReplicaId()
    {
        return replicaId;
    }

    /**
     * Sets the ID of the replica this configuration is configuring.
     */
    public void setReplicaId( ReplicaId replicaId )
    {
        assert replicaId != null;
        this.replicaId = replicaId;
    }

    /**
     * Returns the {@link ReplicationStore} which stores the change log
     * of the replica this configuration is configuring.  The default
     * implementation is {@link DerbyReplicationStore}.
     */
    public ReplicationStore getStore()
    {
        return store;
    }

    /**
     * Sets the {@link ReplicationStore} which stores the change log
     * of the replica this configuration is configuring.  The default
     * implementation is {@link DerbyReplicationStore}.
     */
    public void setStore( ReplicationStore store )
    {
        this.store = store;
    }

    /**
     * Returns the {@link UUIDFactory} which generates {@link UUID}s for
     * new directory entries.  The default implementation is
     * {@link DefaultUUIDFactory}.
     */
    public UUIDFactory getUuidFactory()
    {
        return uuidFactory;
    }

    /**
     * Sets the {@link UUIDFactory} which generates {@link UUID}s for
     * new directory entries.  The default implementation is
     * {@link DefaultUUIDFactory}.
     */
    public void setUuidFactory( UUIDFactory uuidFactory )
    {
        this.uuidFactory = uuidFactory;
    }

    /**
     * Returns the maximum age (days) of change logs stored in
     * {@link ReplicationStore}.  Any change logs and deleted entries
     * older than this value will be purged periodically.  The default value
     * is {@link #DEFAULT_LOG_MAX_AGE}.
     */
    public int getLogMaxAge()
    {
        return logMaxAge;
    }

    /**
     * Sets the maximum age (days) of change logs stored in
     * {@link ReplicationStore}.  Any change logs and deleted entries
     * older than this value will be purged periodically.  The default value
     * is {@link #DEFAULT_LOG_MAX_AGE}.
     */
    public void setLogMaxAge( int logMaxAge )
    {
        if ( logMaxAge <= 0 )
        {
            throw new ReplicationConfigurationException( "logMaxAge: " + logMaxAge );
        }

        this.logMaxAge = logMaxAge;
    }


    /**
     * Validate Mitosis configuration.
     * 
     * We check that the configuration file contains valid
     * parameters :<br/>
     *  - a replicaId<br/>
     *  - a valid server port (between 0 and 65535)<br/>
     *  - a valid response timeout ( > 0 )<br/>
     *  - a uuidFactory<br/>
     *  - a CSN factory<br/>
     *  - a store (derby)<br/>
     *  - a list of valid replica, none of them being equal
     *  to the replicaId 
     *
     * @throws ReplicationConfigurationException If the configuration file is invalid
     */
    public void validate() throws ReplicationConfigurationException
    {
        if ( replicaId == null )
        {
            log.error( "The replicaId is missing" );
            throw new ReplicationConfigurationException( "Replica ID is not specified." );
        }

        if ( ( serverPort < 0 ) || ( serverPort > 65535 ) )
        {
            log.error( "The replica port is not between 0 and 65535" );
            throw new ReplicationConfigurationException( "Server port is invalid: " + serverPort );
        }

        if ( responseTimeout <= 0 )
        {
            log.error( "The replica responsetimeout is negative" );
            throw new ReplicationConfigurationException( "Invalid response timeout: " + responseTimeout );
        }

        if ( uuidFactory == null )
        {
            log.error( "The UUID factory has not been declared" );
            throw new ReplicationConfigurationException( "UUID factory is not specified." );
        }

        if ( csnFactory == null )
        {
            log.error( "The CSN factory has not been declared" );
            throw new ReplicationConfigurationException( "CSN factory is not specified." );
        }

        if ( store == null )
        {
            log.error( "The store has not been declared" );
            throw new ReplicationConfigurationException( "Replication store is not specified." );
        }

        if ( peerReplicas.size() == 0 )
        {
            log.error( "The replicas peer list is empty" );
            throw new ReplicationConfigurationException( "No peer replicas" );
        }

        // Check the peer replicas.
        // We should check that no replica has the same Id, and that we don't
        // have two replicas on the same server with the same port
        Set<String> ids = new TreeSet<String>();
        Map<String, Integer> servers = new HashMap<String, Integer>();

        // Initialize the set with this server replicaId
        ids.add( replicaId.getId() );

        // And store the local inetadress
        servers.put( "localhost", serverPort );
        servers.put( "127.0.0.1", serverPort );

        try
        {
            servers.put( StringTools.lowerCase( InetAddress.getByName( "127.0.0.1" ).getHostName() ), serverPort );
        }
        catch ( UnknownHostException uhe )
        {
            // Should never occurs with 127.0.0.1
            throw new ReplicationConfigurationException( "Unknown host name" );
        }

        for ( Replica peer:peerReplicas )
        {
            if ( ids.contains( peer.getId().getId() ) )
            {
                log.error( "Peer replica ID '{}' has already been declared.", peer.getId() );
                throw new ReplicationConfigurationException( "Peer replica ID '" + peer.getId()
                    + "' has already been declared." );
            }

            // Now check that we don't already have a replica on a server with the same port 
            String replicaServer = StringTools.lowerCase( peer.getAddress().getHostName() );
            int replicaPort = peer.getAddress().getPort();

            if ( servers.containsKey( replicaServer ) )
            {
                int peerPort = servers.get( replicaServer );

                if ( replicaPort == peerPort )
                {
                    log.error(
                        "The replica in the peer list has already been declared on the server {} with the port {}",
                        replicaServer, peerPort );
                    throw new ReplicationConfigurationException( "Replication store is not specified." );
                }
            }

            servers.put( replicaServer, replicaPort );
        }
    }
}
