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


import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.apache.directory.server.dns.DnsException;
import org.apache.directory.server.dns.messages.DnsMessage;
import org.apache.directory.server.dns.messages.DnsMessageModifier;
import org.apache.directory.server.dns.messages.MessageType;
import org.apache.directory.server.dns.messages.OpCode;
import org.apache.directory.server.dns.messages.QuestionRecord;
import org.apache.directory.server.dns.messages.ResourceRecord;
import org.apache.directory.server.dns.messages.ResponseCode;
import org.apache.directory.server.dns.store.RecordStore;
import org.apache.directory.server.i18n.I18n;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * Domain Name Service (DNS) Protocol (RFC 1034, 1035)
 * 
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
public class DomainNameService
{
    /** the log for this class */
    private static final Logger LOG = LoggerFactory.getLogger( DomainNameService.class );


    /**
     * Creates a new instance of DomainNameService.
     */
    public static void execute( DnsContext dnsContext, DnsMessage request ) throws Exception
    {
        if ( LOG.isDebugEnabled() )
        {
            monitorRequest( request );
        }

        getResourceRecords( dnsContext, request );

        if ( LOG.isDebugEnabled() )
        {
            monitorContext( dnsContext );
        }

        buildReply( dnsContext, request );

        if ( LOG.isDebugEnabled() )
        {
            monitorReply( dnsContext );
        }
    }


    private static void monitorRequest( DnsMessage request ) throws Exception
    {
        try
        {
            LOG.debug( monitorMessage( request, "request" ) );
        }
        catch ( Exception e )
        {
            // This is a monitor.  No exceptions should bubble up.
            LOG.error( I18n.err( I18n.ERR_153 ), e );
        }
    }


    private static void getResourceRecords( DnsContext dnsContext, DnsMessage request ) throws Exception
    {
        RecordStore store = dnsContext.getStore();

        List<QuestionRecord> questions = request.getQuestionRecords();

        Iterator<QuestionRecord> it = questions.iterator();

        while ( it.hasNext() )
        {
            dnsContext.addResourceRecords( getEntry( store, it.next() ) );
        }
    }


    /**
     * Returns a set of {@link ResourceRecord}s from a {@link RecordStore}, given a DNS {@link QuestionRecord}.
     *
     * @param store
     * @param question
     * @return The set of {@link ResourceRecord}s.
     * @throws DNSException
     */
    private static Set<ResourceRecord> getEntry( RecordStore store, QuestionRecord question ) throws DnsException
    {
        Set<ResourceRecord> records = null;

        records = store.getRecords( question );

        if ( records == null || records.isEmpty() )
        {
            LOG.debug( "The domain name referenced in the query does not exist." );

            throw new DnsException( ResponseCode.NAME_ERROR );
        }

        return records;
    }


    private static void monitorContext( DnsContext dnsContext ) throws Exception
    {
        try
        {
            RecordStore store = dnsContext.getStore();
            List<ResourceRecord> records = dnsContext.getResourceRecords();

            StringBuffer sb = new StringBuffer();
            sb.append( "Monitoring context:" );
            sb.append( "\n\t" + "store:                     " + store );
            sb.append( "\n\t" + "records:                   " + records );

            LOG.debug( sb.toString() );
        }
        catch ( Exception e )
        {
            // This is a monitor.  No exceptions should bubble up.
            LOG.error( I18n.err( I18n.ERR_154 ), e );
        }
    }


    private static void buildReply( DnsContext dnsContext, DnsMessage request ) throws Exception
    {
        List<ResourceRecord> records = dnsContext.getResourceRecords();

        DnsMessageModifier modifier = new DnsMessageModifier();

        modifier.setTransactionId( request.getTransactionId() );
        modifier.setMessageType( MessageType.RESPONSE );
        modifier.setOpCode( OpCode.QUERY );
        modifier.setAuthoritativeAnswer( false );
        modifier.setTruncated( false );
        modifier.setRecursionDesired( request.isRecursionDesired() );
        modifier.setRecursionAvailable( false );
        modifier.setReserved( false );
        modifier.setAcceptNonAuthenticatedData( false );
        modifier.setResponseCode( ResponseCode.NO_ERROR );
        modifier.setQuestionRecords( request.getQuestionRecords() );

        modifier.setAnswerRecords( records );
        modifier.setAuthorityRecords( new ArrayList<ResourceRecord>() );
        modifier.setAdditionalRecords( new ArrayList<ResourceRecord>() );

        dnsContext.setReply( modifier.getDnsMessage() );
    }


    private static void monitorReply( DnsContext dnsContext ) throws Exception
    {
        try
        {
            DnsMessage reply = dnsContext.getReply();

            LOG.debug( monitorMessage( reply, "reply" ) );
        }
        catch ( Exception e )
        {
            // This is a monitor.  No exceptions should bubble up.
            LOG.error( I18n.err( I18n.ERR_155 ), e );
        }
    }


    private static String monitorMessage( DnsMessage message, String direction )
    {
        MessageType messageType = message.getMessageType();
        OpCode opCode = message.getOpCode();
        ResponseCode responseCode = message.getResponseCode();
        int transactionId = message.getTransactionId();

        StringBuffer sb = new StringBuffer();
        sb.append( "Monitoring " + direction + ":" );
        sb.append( "\n\t" + "messageType                " + messageType );
        sb.append( "\n\t" + "opCode                     " + opCode );
        sb.append( "\n\t" + "responseCode               " + responseCode );
        sb.append( "\n\t" + "transactionId              " + transactionId );

        sb.append( "\n\t" + "authoritativeAnswer        " + message.isAuthoritativeAnswer() );
        sb.append( "\n\t" + "truncated                  " + message.isTruncated() );
        sb.append( "\n\t" + "recursionDesired           " + message.isRecursionDesired() );
        sb.append( "\n\t" + "recursionAvailable         " + message.isRecursionAvailable() );
        sb.append( "\n\t" + "reserved                   " + message.isReserved() );
        sb.append( "\n\t" + "acceptNonAuthenticatedData " + message.isAcceptNonAuthenticatedData() );

        List<QuestionRecord> questions = message.getQuestionRecords();

        sb.append( "\n\t" + "questions:                 " + questions );

        return sb.toString();
    }
}
