// Copyright 2003-2005 Arthur van Hoff, Rick Blair
// Licensed under Apache License version 2.0
// Original license LGPL

package javax.jmdns.impl;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.jmdns.impl.constants.DNSConstants;
import javax.jmdns.impl.constants.DNSRecordClass;

/**
 * An outgoing DNS message.
 * 
 * @author Arthur van Hoff, Rick Blair, Werner Randelshofer
 */
public final class DNSOutgoing extends DNSMessage {

    public static class MessageOutputStream extends ByteArrayOutputStream {
        private final DNSOutgoing _out;

        private final int         _offset;

        /**
         * Creates a new message stream, with a buffer capacity of the specified size, in bytes.
         * 
         * @param size
         *            the initial size.
         * @exception IllegalArgumentException
         *                if size is negative.
         */
        MessageOutputStream(int size, DNSOutgoing out) {
            this(size, out, 0);
        }

        MessageOutputStream(int size, DNSOutgoing out, int offset) {
            super(size);
            _out = out;
            _offset = offset;
        }

        void writeByte(int value) {
            this.write(value & 0xFF);
        }

        void writeBytes(String str, int off, int len) {
            for (int i = 0; i < len; i++) {
                writeByte(str.charAt(off + i));
            }
        }

        void writeBytes(byte data[]) {
            if (data != null) {
                writeBytes(data, 0, data.length);
            }
        }

        void writeBytes(byte data[], int off, int len) {
            for (int i = 0; i < len; i++) {
                writeByte(data[off + i]);
            }
        }

        void writeShort(int value) {
            writeByte(value >> 8);
            writeByte(value);
        }

        void writeInt(int value) {
            writeShort(value >> 16);
            writeShort(value);
        }

        void writeUTF(String str, int off, int len) {
            // compute utf length
            int utflen = 0;
            for (int i = 0; i < len; i++) {
                int ch = str.charAt(off + i);
                if ((ch >= 0x0001) && (ch <= 0x007F)) {
                    utflen += 1;
                } else {
                    if (ch > 0x07FF) {
                        utflen += 3;
                    } else {
                        utflen += 2;
                    }
                }
            }
            // write utf length
            writeByte(utflen);
            // write utf data
            for (int i = 0; i < len; i++) {
                int ch = str.charAt(off + i);
                if ((ch >= 0x0001) && (ch <= 0x007F)) {
                    writeByte(ch);
                } else {
                    if (ch > 0x07FF) {
                        writeByte(0xE0 | ((ch >> 12) & 0x0F));
                        writeByte(0x80 | ((ch >> 6) & 0x3F));
                        writeByte(0x80 | ((ch >> 0) & 0x3F));
                    } else {
                        writeByte(0xC0 | ((ch >> 6) & 0x1F));
                        writeByte(0x80 | ((ch >> 0) & 0x3F));
                    }
                }
            }
        }

        void writeName(String name) {
            writeName(name, true);
        }

        void writeName(String name, boolean useCompression) {
            String aName = name;
            while (true) {
                int n = aName.indexOf('.');
                if (n < 0) {
                    n = aName.length();
                }
                if (n <= 0) {
                    writeByte(0);
                    return;
                }
                String label = aName.substring(0, n);
                if (useCompression && USE_DOMAIN_NAME_COMPRESSION) {
                    Integer offset = _out._names.get(aName);
                    if (offset != null) {
                        int val = offset.intValue();
                        writeByte((val >> 8) | 0xC0);
                        writeByte(val & 0xFF);
                        return;
                    }
                    _out._names.put(aName, Integer.valueOf(this.size() + _offset));
                    writeUTF(label, 0, label.length());
                } else {
                    writeUTF(label, 0, label.length());
                }
                aName = aName.substring(n);
                if (aName.startsWith(".")) {
                    aName = aName.substring(1);
                }
            }
        }

        void writeQuestion(DNSQuestion question) {
            writeName(question.getName());
            writeShort(question.getRecordType().indexValue());
            writeShort(question.getRecordClass().indexValue());
        }

        void writeRecord(DNSRecord rec, long now) {
            writeName(rec.getName());
            writeShort(rec.getRecordType().indexValue());
            writeShort(rec.getRecordClass().indexValue() | ((rec.isUnique() && _out.isMulticast()) ? DNSRecordClass.CLASS_UNIQUE : 0));
            writeInt((now == 0) ? rec.getTTL() : rec.getRemainingTTL(now));

            // We need to take into account the 2 size bytes
            MessageOutputStream record = new MessageOutputStream(512, _out, _offset + this.size() + 2);
            rec.write(record);
            byte[] byteArray = record.toByteArray();

            writeShort(byteArray.length);
            write(byteArray, 0, byteArray.length);
        }

    }

    /**
     * This can be used to turn off domain name compression. This was helpful for tracking problems interacting with other mdns implementations.
     */
    public static boolean             USE_DOMAIN_NAME_COMPRESSION = true;

    Map<String, Integer>              _names;

    private int                       _maxUDPPayload;

    private final MessageOutputStream _questionsBytes;

    private final MessageOutputStream _answersBytes;

    private final MessageOutputStream _authoritativeAnswersBytes;

    private final MessageOutputStream _additionalsAnswersBytes;

    private final static int          HEADER_SIZE                 = 12;

    /**
     * Create an outgoing multicast query or response.
     * 
     * @param flags
     */
    public DNSOutgoing(int flags) {
        this(flags, true, DNSConstants.MAX_MSG_TYPICAL);
    }

    /**
     * Create an outgoing query or response.
     * 
     * @param flags
     * @param multicast
     */
    public DNSOutgoing(int flags, boolean multicast) {
        this(flags, multicast, DNSConstants.MAX_MSG_TYPICAL);
    }

    /**
     * Create an outgoing query or response.
     * 
     * @param flags
     * @param multicast
     * @param senderUDPPayload
     *            The sender's UDP payload size is the number of bytes of the largest UDP payload that can be reassembled and delivered in the sender's network stack.
     */
    public DNSOutgoing(int flags, boolean multicast, int senderUDPPayload) {
        super(flags, 0, multicast);
        _names = new HashMap<String, Integer>();
        _maxUDPPayload = (senderUDPPayload > 0 ? senderUDPPayload : DNSConstants.MAX_MSG_TYPICAL);
        _questionsBytes = new MessageOutputStream(senderUDPPayload, this);
        _answersBytes = new MessageOutputStream(senderUDPPayload, this);
        _authoritativeAnswersBytes = new MessageOutputStream(senderUDPPayload, this);
        _additionalsAnswersBytes = new MessageOutputStream(senderUDPPayload, this);
    }

    /**
     * Return the number of byte available in the message.
     * 
     * @return available space
     */
    public int availableSpace() {
        return _maxUDPPayload - HEADER_SIZE - _questionsBytes.size() - _answersBytes.size() - _authoritativeAnswersBytes.size() - _additionalsAnswersBytes.size();
    }

    /**
     * Add a question to the message.
     * 
     * @param rec
     * @exception IOException
     */
    public void addQuestion(DNSQuestion rec) throws IOException {
        MessageOutputStream record = new MessageOutputStream(512, this);
        record.writeQuestion(rec);
        byte[] byteArray = record.toByteArray();
        if (byteArray.length < this.availableSpace()) {
            _questions.add(rec);
            _questionsBytes.write(byteArray, 0, byteArray.length);
        } else {
            throw new IOException("message full");
        }
    }

    /**
     * Add an answer if it is not suppressed.
     * 
     * @param in
     * @param rec
     * @exception IOException
     */
    public void addAnswer(DNSIncoming in, DNSRecord rec) throws IOException {
        if ((in == null) || !rec.suppressedBy(in)) {
            this.addAnswer(rec, 0);
        }
    }

    /**
     * Add an answer to the message.
     * 
     * @param rec
     * @param now
     * @exception IOException
     */
    public void addAnswer(DNSRecord rec, long now) throws IOException {
        if (rec != null) {
            if ((now == 0) || !rec.isExpired(now)) {
                MessageOutputStream record = new MessageOutputStream(512, this);
                record.writeRecord(rec, now);
                byte[] byteArray = record.toByteArray();
                if (byteArray.length < this.availableSpace()) {
                    _answers.add(rec);
                    _answersBytes.write(byteArray, 0, byteArray.length);
                } else {
                    throw new IOException("message full");
                }
            }
        }
    }

    /**
     * Add an authoritative answer to the message.
     * 
     * @param rec
     * @exception IOException
     */
    public void addAuthorativeAnswer(DNSRecord rec) throws IOException {
        MessageOutputStream record = new MessageOutputStream(512, this);
        record.writeRecord(rec, 0);
        byte[] byteArray = record.toByteArray();
        if (byteArray.length < this.availableSpace()) {
            _authoritativeAnswers.add(rec);
            _authoritativeAnswersBytes.write(byteArray, 0, byteArray.length);
        } else {
            throw new IOException("message full");
        }
    }

    /**
     * Add an additional answer to the record. Omit if there is no room.
     * 
     * @param in
     * @param rec
     * @exception IOException
     */
    public void addAdditionalAnswer(DNSIncoming in, DNSRecord rec) throws IOException {
        MessageOutputStream record = new MessageOutputStream(512, this);
        record.writeRecord(rec, 0);
        byte[] byteArray = record.toByteArray();
        if (byteArray.length < this.availableSpace()) {
            _additionals.add(rec);
            _additionalsAnswersBytes.write(byteArray, 0, byteArray.length);
        } else {
            throw new IOException("message full");
        }
    }

    /**
     * Builds the final message buffer to be send and returns it.
     * 
     * @return bytes to send.
     */
    public byte[] data() {
        long now = System.currentTimeMillis(); // System.currentTimeMillis()
        _names.clear();

        MessageOutputStream message = new MessageOutputStream(_maxUDPPayload, this);
        message.writeShort(_multicast ? 0 : this.getId());
        message.writeShort(this.getFlags());
        message.writeShort(this.getNumberOfQuestions());
        message.writeShort(this.getNumberOfAnswers());
        message.writeShort(this.getNumberOfAuthorities());
        message.writeShort(this.getNumberOfAdditionals());
        for (DNSQuestion question : _questions) {
            message.writeQuestion(question);
        }
        for (DNSRecord record : _answers) {
            message.writeRecord(record, now);
        }
        for (DNSRecord record : _authoritativeAnswers) {
            message.writeRecord(record, now);
        }
        for (DNSRecord record : _additionals) {
            message.writeRecord(record, now);
        }
        return message.toByteArray();
    }

    @Override
    public boolean isQuery() {
        return (this.getFlags() & DNSConstants.FLAGS_QR_MASK) == DNSConstants.FLAGS_QR_QUERY;
    }

    /**
     * Debugging.
     */
    String print(boolean dump) {
        StringBuilder buf = new StringBuilder();
        buf.append(this.print());
        if (dump) {
            buf.append(this.print(this.data()));
        }
        return buf.toString();
    }

    @Override
    public String toString() {
        StringBuffer buf = new StringBuffer();
        buf.append(isQuery() ? "dns[query:" : "dns[response:");
        buf.append(" id=0x");
        buf.append(Integer.toHexString(this.getId()));
        if (this.getFlags() != 0) {
            buf.append(", flags=0x");
            buf.append(Integer.toHexString(this.getFlags()));
            if ((this.getFlags() & DNSConstants.FLAGS_QR_RESPONSE) != 0) {
                buf.append(":r");
            }
            if ((this.getFlags() & DNSConstants.FLAGS_AA) != 0) {
                buf.append(":aa");
            }
            if ((this.getFlags() & DNSConstants.FLAGS_TC) != 0) {
                buf.append(":tc");
            }
        }
        if (this.getNumberOfQuestions() > 0) {
            buf.append(", questions=");
            buf.append(this.getNumberOfQuestions());
        }
        if (this.getNumberOfAnswers() > 0) {
            buf.append(", answers=");
            buf.append(this.getNumberOfAnswers());
        }
        if (this.getNumberOfAuthorities() > 0) {
            buf.append(", authorities=");
            buf.append(this.getNumberOfAuthorities());
        }
        if (this.getNumberOfAdditionals() > 0) {
            buf.append(", additionals=");
            buf.append(this.getNumberOfAdditionals());
        }
        if (this.getNumberOfQuestions() > 0) {
            buf.append("\nquestions:");
            for (DNSQuestion question : _questions) {
                buf.append("\n\t");
                buf.append(question);
            }
        }
        if (this.getNumberOfAnswers() > 0) {
            buf.append("\nanswers:");
            for (DNSRecord record : _answers) {
                buf.append("\n\t");
                buf.append(record);
            }
        }
        if (this.getNumberOfAuthorities() > 0) {
            buf.append("\nauthorities:");
            for (DNSRecord record : _authoritativeAnswers) {
                buf.append("\n\t");
                buf.append(record);
            }
        }
        if (this.getNumberOfAdditionals() > 0) {
            buf.append("\nadditionals:");
            for (DNSRecord record : _additionals) {
                buf.append("\n\t");
                buf.append(record);
            }
        }
        buf.append("\nnames=");
        buf.append(_names);
        buf.append("]");
        return buf.toString();
    }

    /**
     * @return the maxUDPPayload
     */
    public int getMaxUDPPayload() {
        return this._maxUDPPayload;
    }

}
