/* -*- Mode: Java; tab-width: 4 -*-
 *
 * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
 *
 * Licensed 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.

 To do:
 - implement remove()
 - fix set() to replace existing values
 */

package com.android.net.module.util;

import android.os.Parcelable;
import android.os.Parcel;

import java.util.Arrays;

/**
 * This class handles TXT record data for DNS based service discovery as specified at
 * http://tools.ietf.org/html/draft-cheshire-dnsext-dns-sd-11
 *
 * DNS-SD specifies that a TXT record corresponding to an SRV record consist of
 * a packed array of bytes, each preceded by a length byte. Each string
 * is an attribute-value pair.
 *
 * The DnsSdTxtRecord object stores the entire TXT data as a single byte array, traversing it
 * as need be to implement its various methods.
 * @hide
 *
 */
public class DnsSdTxtRecord implements Parcelable {
    private static final byte mSeparator = '=';

    private byte[] mData;

    /** Constructs a new, empty TXT record. */
    public DnsSdTxtRecord()  {
        mData = new byte[0];
    }

    /** Constructs a new TXT record from a byte array in the standard format. */
    public DnsSdTxtRecord(byte[] data) {
        mData = (byte[]) data.clone();
    }

    /** Copy constructor */
    public DnsSdTxtRecord(DnsSdTxtRecord src) {
        if (src != null && src.mData != null) {
            mData = (byte[]) src.mData.clone();
        }
    }

    /**
     * Set a key/value pair. Setting an existing key will replace its value.
     * @param key Must be ascii with no '='
     * @param value matching value to key
     */
    public void set(String key, String value) {
        byte[] keyBytes;
        byte[] valBytes;
        int valLen;

        if (value != null) {
            valBytes = value.getBytes();
            valLen = valBytes.length;
        } else {
            valBytes = null;
            valLen = 0;
        }

        try {
            keyBytes = key.getBytes("US-ASCII");
        }
        catch (java.io.UnsupportedEncodingException e) {
            throw new IllegalArgumentException("key should be US-ASCII");
        }

        for (int i = 0; i < keyBytes.length; i++) {
            if (keyBytes[i] == '=') {
                throw new IllegalArgumentException("= is not a valid character in key");
            }
        }

        if (keyBytes.length + valLen >= 255) {
            throw new IllegalArgumentException("Key and Value length cannot exceed 255 bytes");
        }

        int currentLoc = remove(key);
        if (currentLoc == -1)
            currentLoc = keyCount();

        insert(keyBytes, valBytes, currentLoc);
    }

    /**
     * Get a value for a key
     *
     * @param key
     * @return The value associated with the key
     */
    public String get(String key) {
        byte[] val = this.getValue(key);
        return val != null ? new String(val) : null;
    }

    /** Remove a key/value pair. If found, returns the index or -1 if not found */
    public int remove(String key) {
        int avStart = 0;

        for (int i=0; avStart < mData.length; i++) {
            int avLen = mData[avStart];
            if (key.length() <= avLen &&
                    (key.length() == avLen || mData[avStart + key.length() + 1] == mSeparator)) {
                String s = new String(mData, avStart + 1, key.length());
                if (0 == key.compareToIgnoreCase(s)) {
                    byte[] oldBytes = mData;
                    mData = new byte[oldBytes.length - avLen - 1];
                    System.arraycopy(oldBytes, 0, mData, 0, avStart);
                    System.arraycopy(oldBytes, avStart + avLen + 1, mData, avStart,
                            oldBytes.length - avStart - avLen - 1);
                    return i;
                }
            }
            avStart += (0xFF & (avLen + 1));
        }
        return -1;
    }

    /** Return the count of keys */
    public int keyCount() {
        int count = 0, nextKey;
        for (nextKey = 0; nextKey < mData.length; count++) {
            nextKey += (0xFF & (mData[nextKey] + 1));
        }
        return count;
    }

    /** Return true if key is present, false if not. */
    public boolean contains(String key) {
        String s = null;
        for (int i = 0; null != (s = this.getKey(i)); i++) {
            if (0 == key.compareToIgnoreCase(s)) return true;
        }
        return false;
    }

    /* Gets the size in bytes */
    public int size() {
        return mData.length;
    }

    /* Gets the raw data in bytes */
    public byte[] getRawData() {
        return (byte[]) mData.clone();
    }

    private void insert(byte[] keyBytes, byte[] value, int index) {
        byte[] oldBytes = mData;
        int valLen = (value != null) ? value.length : 0;
        int insertion = 0;
        int newLen, avLen;

        for (int i = 0; i < index && insertion < mData.length; i++) {
            insertion += (0xFF & (mData[insertion] + 1));
        }

        avLen = keyBytes.length + valLen + (value != null ? 1 : 0);
        newLen = avLen + oldBytes.length + 1;

        mData = new byte[newLen];
        System.arraycopy(oldBytes, 0, mData, 0, insertion);
        int secondHalfLen = oldBytes.length - insertion;
        System.arraycopy(oldBytes, insertion, mData, newLen - secondHalfLen, secondHalfLen);
        mData[insertion] = (byte) avLen;
        System.arraycopy(keyBytes, 0, mData, insertion + 1, keyBytes.length);
        if (value != null) {
            mData[insertion + 1 + keyBytes.length] = mSeparator;
            System.arraycopy(value, 0, mData, insertion + keyBytes.length + 2, valLen);
        }
    }

    /** Return a key in the TXT record by zero-based index. Returns null if index exceeds the total number of keys. */
    private String getKey(int index) {
        int avStart = 0;

        for (int i=0; i < index && avStart < mData.length; i++) {
            avStart += mData[avStart] + 1;
        }

        if (avStart < mData.length) {
            int avLen = mData[avStart];
            int aLen = 0;

            for (aLen=0; aLen < avLen; aLen++) {
                if (mData[avStart + aLen + 1] == mSeparator) break;
            }
            return new String(mData, avStart + 1, aLen);
        }
        return null;
    }

    /**
     * Look up a key in the TXT record by zero-based index and return its value.
     * Returns null if index exceeds the total number of keys.
     * Returns null if the key is present with no value.
     */
    private byte[] getValue(int index) {
        int avStart = 0;
        byte[] value = null;

        for (int i=0; i < index && avStart < mData.length; i++) {
            avStart += mData[avStart] + 1;
        }

        if (avStart < mData.length) {
            int avLen = mData[avStart];
            int aLen = 0;

            for (aLen=0; aLen < avLen; aLen++) {
                if (mData[avStart + aLen + 1] == mSeparator) {
                    value = new byte[avLen - aLen - 1];
                    System.arraycopy(mData, avStart + aLen + 2, value, 0, avLen - aLen - 1);
                    break;
                }
            }
        }
        return value;
    }

    private String getValueAsString(int index) {
        byte[] value = this.getValue(index);
        return value != null ? new String(value) : null;
    }

    private byte[] getValue(String forKey) {
        String s = null;
        int i;

        for (i = 0; null != (s = this.getKey(i)); i++) {
            if (0 == forKey.compareToIgnoreCase(s)) {
                return this.getValue(i);
            }
        }

        return null;
    }

    /**
     * Return a string representation.
     * Example : {key1=value1},{key2=value2}..
     *
     * For a key say like "key3" with null value
     * {key1=value1},{key2=value2}{key3}
     */
    public String toString() {
        String a, result = null;

        for (int i = 0; null != (a = this.getKey(i)); i++) {
            String av =  "{" + a;
            String val = this.getValueAsString(i);
            if (val != null)
                av += "=" + val + "}";
            else
                av += "}";
            if (result == null)
                result = av;
            else
                result = result + ", " + av;
        }
        return result != null ? result : "";
    }

    @Override
    public boolean equals(Object o) {
        if (o == this) {
            return true;
        }
        if (!(o instanceof DnsSdTxtRecord)) {
            return false;
        }

        DnsSdTxtRecord record = (DnsSdTxtRecord)o;
        return  Arrays.equals(record.mData, mData);
    }

    @Override
    public int hashCode() {
        return Arrays.hashCode(mData);
    }

    /** Implement the Parcelable interface */
    public int describeContents() {
        return 0;
    }

    /** Implement the Parcelable interface */
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeByteArray(mData);
    }

    /** Implement the Parcelable interface */
    public static final @android.annotation.NonNull Creator<DnsSdTxtRecord> CREATOR =
        new Creator<DnsSdTxtRecord>() {
            public DnsSdTxtRecord createFromParcel(Parcel in) {
                DnsSdTxtRecord info = new DnsSdTxtRecord();
                in.readByteArray(info.mData);
                return info;
            }

            public DnsSdTxtRecord[] newArray(int size) {
                return new DnsSdTxtRecord[size];
            }
        };
}
