/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * 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.
 */

package android.nfc;

import java.nio.ByteBuffer;
import java.util.Arrays;

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


/**
 * Represents an immutable NDEF Message.
 * <p>
 * NDEF (NFC Data Exchange Format) is a light-weight binary format,
 * used to encapsulate typed data. It is specified by the NFC Forum,
 * for transmission and storage with NFC, however it is transport agnostic.
 * <p>
 * NDEF defines messages and records. An NDEF Record contains
 * typed data, such as MIME-type media, a URI, or a custom
 * application payload. An NDEF Message is a container for
 * one or more NDEF Records.
 * <p>
 * When an Android device receives an NDEF Message
 * (for example by reading an NFC tag) it processes it through
 * a dispatch mechanism to determine an activity to launch.
 * The type of the <em>first</em> record in the message has
 * special importance for message dispatch, so design this record
 * carefully.
 * <p>
 * Use {@link #NdefMessage(byte[])} to construct an NDEF Message from
 * binary data, or {@link #NdefMessage(NdefRecord[])} to
 * construct from one or more {@link NdefRecord}s.
 * <p class="note">
 * {@link NdefMessage} and {@link NdefRecord} implementations are
 * always available, even on Android devices that do not have NFC hardware.
 * <p class="note">
 * {@link NdefRecord}s are intended to be immutable (and thread-safe),
 * however they may contain mutable fields. So take care not to modify
 * mutable fields passed into constructors, or modify mutable fields
 * obtained by getter methods, unless such modification is explicitly
 * marked as safe.
 *
 * @see NfcAdapter#ACTION_NDEF_DISCOVERED
 * @see NdefRecord
 */
public final class NdefMessage implements Parcelable {
    private final NdefRecord[] mRecords;

    /**
     * Construct an NDEF Message by parsing raw bytes.<p>
     * Strict validation of the NDEF binary structure is performed:
     * there must be at least one record, every record flag must
     * be correct, and the total length of the message must match
     * the length of the input data.<p>
     * This parser can handle chunked records, and converts them
     * into logical {@link NdefRecord}s within the message.<p>
     * Once the input data has been parsed to one or more logical
     * records, basic validation of the tnf, type, id, and payload fields
     * of each record is performed, as per the documentation on
     * on {@link NdefRecord#NdefRecord(short, byte[], byte[], byte[])}<p>
     * If either strict validation of the binary format fails, or
     * basic validation during record construction fails, a
     * {@link FormatException} is thrown<p>
     * Deep inspection of the type, id and payload fields of
     * each record is not performed, so it is possible to parse input
     * that has a valid binary format and confirms to the basic
     * validation requirements of
     * {@link NdefRecord#NdefRecord(short, byte[], byte[], byte[])},
     * but fails more strict requirements as specified by the
     * NFC Forum.
     *
     * <p class="note">
     * It is safe to re-use the data byte array after construction:
     * this constructor will make an internal copy of all necessary fields.
     *
     * @param data raw bytes to parse
     * @throws FormatException if the data cannot be parsed
     */
    public NdefMessage(byte[] data) throws FormatException {
        if (data == null) throw new NullPointerException("data is null");
        ByteBuffer buffer = ByteBuffer.wrap(data);

        mRecords = NdefRecord.parse(buffer, false);

        if (buffer.remaining() > 0) {
            throw new FormatException("trailing data");
        }
    }

    /**
     * Construct an NDEF Message from one or more NDEF Records.
     *
     * @param record first record (mandatory)
     * @param records additional records (optional)
     */
    public NdefMessage(NdefRecord record, NdefRecord ... records) {
        // validate
        if (record == null) throw new NullPointerException("record cannot be null");

        for (NdefRecord r : records) {
            if (r == null) {
                throw new NullPointerException("record cannot be null");
            }
        }

        mRecords = new NdefRecord[1 + records.length];
        mRecords[0] = record;
        System.arraycopy(records, 0, mRecords, 1, records.length);
    }

    /**
     * Construct an NDEF Message from one or more NDEF Records.
     *
     * @param records one or more records
     */
    public NdefMessage(NdefRecord[] records) {
        // validate
        if (records.length < 1) {
            throw new IllegalArgumentException("must have at least one record");
        }
        for (NdefRecord r : records) {
            if (r == null) {
                throw new NullPointerException("records cannot contain null");
            }
        }

        mRecords = records;
    }

    /**
     * Get the NDEF Records inside this NDEF Message.<p>
     * An {@link NdefMessage} always has one or more NDEF Records: so the
     * following code to retrieve the first record is always safe
     * (no need to check for null or array length >= 1):
     * <pre>
     * NdefRecord firstRecord = ndefMessage.getRecords()[0];
     * </pre>
     *
     * @return array of one or more NDEF records.
     */
    public NdefRecord[] getRecords() {
        return mRecords;
    }

    /**
     * Return the length of this NDEF Message if it is written to a byte array
     * with {@link #toByteArray}.<p>
     * An NDEF Message can be formatted to bytes in different ways
     * depending on chunking, SR, and ID flags, so the length returned
     * by this method may not be equal to the length of the original
     * byte array used to construct this NDEF Message. However it will
     * always be equal to the length of the byte array produced by
     * {@link #toByteArray}.
     *
     * @return length of this NDEF Message when written to bytes with {@link #toByteArray}
     * @see #toByteArray
     */
    public int getByteArrayLength() {
        int length = 0;
        for (NdefRecord r : mRecords) {
            length += r.getByteLength();
        }
        return length;
    }

    /**
     * Return this NDEF Message as raw bytes.<p>
     * The NDEF Message is formatted as per the NDEF 1.0 specification,
     * and the byte array is suitable for network transmission or storage
     * in an NFC Forum NDEF compatible tag.<p>
     * This method will not chunk any records, and will always use the
     * short record (SR) format and omit the identifier field when possible.
     *
     * @return NDEF Message in binary format
     * @see getByteArrayLength
     */
    public byte[] toByteArray() {
        int length = getByteArrayLength();
        ByteBuffer buffer = ByteBuffer.allocate(length);

        for (int i=0; i<mRecords.length; i++) {
            boolean mb = (i == 0);  // first record
            boolean me = (i == mRecords.length - 1);  // last record
            mRecords[i].writeToByteBuffer(buffer, mb, me);
        }

        return buffer.array();
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(mRecords.length);
        dest.writeTypedArray(mRecords, flags);
    }

    public static final Parcelable.Creator<NdefMessage> CREATOR =
            new Parcelable.Creator<NdefMessage>() {
        @Override
        public NdefMessage createFromParcel(Parcel in) {
            int recordsLength = in.readInt();
            NdefRecord[] records = new NdefRecord[recordsLength];
            in.readTypedArray(records, NdefRecord.CREATOR);
            return new NdefMessage(records);
        }
        @Override
        public NdefMessage[] newArray(int size) {
            return new NdefMessage[size];
        }
    };

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

    /**
     * Returns true if the specified NDEF Message contains
     * identical NDEF Records.
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null) return false;
        if (getClass() != obj.getClass()) return false;
        NdefMessage other = (NdefMessage) obj;
        return Arrays.equals(mRecords, other.mRecords);
    }

    @Override
    public String toString() {
        return "NdefMessage " + Arrays.toString(mRecords);
    }
}