/*
 * Copyright (C) 2011 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 com.android.nfc.snep;

import android.nfc.FormatException;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import com.android.nfc.NfcService;
import com.android.nfc.sneptest.DtaSnepClient;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;

public final class SnepMessage {
    public static final byte VERSION_MAJOR = (byte) 0x1;
    public static final byte VERSION_MINOR = (byte) 0x0;
    public static final byte VERSION = (0xF0 & (VERSION_MAJOR << 4)) | (0x0F & VERSION_MINOR);

    public static final byte REQUEST_CONTINUE = (byte) 0x00;
    public static final byte REQUEST_GET = (byte) 0x01;
    public static final byte REQUEST_PUT = (byte) 0x02;
    public static final byte REQUEST_RFU = (byte) 0x03;
    public static final byte REQUEST_REJECT = (byte) 0x7F;

    public static final byte RESPONSE_CONTINUE = (byte) 0x80;
    public static final byte RESPONSE_SUCCESS = (byte) 0x81;
    public static final byte RESPONSE_NOT_FOUND = (byte) 0xC0;
    public static final byte RESPONSE_EXCESS_DATA = (byte) 0xC1;
    public static final byte RESPONSE_BAD_REQUEST = (byte) 0xC2;
    public static final byte RESPONSE_NOT_IMPLEMENTED = (byte) 0xE0;
    public static final byte RESPONSE_UNSUPPORTED_VERSION = (byte) 0xE1;
    public static final byte RESPONSE_REJECT = (byte) 0xFF;

    private static final byte[] NDEF_SHORT_TEST_RECORD = new byte[]{(byte)0xD1,(byte)0x01,(byte)0x1E,(byte)0x54,(byte)0x02,(byte)0x6C,(byte)0x61, // NDEF Header
            (byte)0x4C,(byte)0x6F,(byte)0x72,(byte)0x65,(byte)0x6D,(byte)0x20,(byte)0x69,(byte)0x70,(byte)0x73,(byte)0x75, // Payload
            (byte)0x6D,(byte)0x20,(byte)0x64,(byte)0x6F,(byte)0x6C,(byte)0x6F,(byte)0x72,(byte)0x20,(byte)0x73,(byte)0x69,
            (byte)0x74,(byte)0x20,(byte)0x61,(byte)0x6D,(byte)0x65,(byte)0x74,(byte)0x2E};

    private static final byte[] NDEF_TEST_RECORD = new byte[]{(byte)0xC1,(byte)0x01,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x1E,(byte)0x54,(byte)0x02,(byte)0x6C,(byte)0x61, // NDEF Header
            (byte)0x4C,(byte)0x6F,(byte)0x72,(byte)0x65,(byte)0x6D,(byte)0x20,(byte)0x69,(byte)0x70,(byte)0x73,(byte)0x75, // Payload
            (byte)0x6D,(byte)0x20,(byte)0x64,(byte)0x6F,(byte)0x6C,(byte)0x6F,(byte)0x72,(byte)0x20,(byte)0x73,(byte)0x69,
            (byte)0x74,(byte)0x20,(byte)0x61,(byte)0x6D,(byte)0x65,(byte)0x74,(byte)0x2E};

    private static final int HEADER_LENGTH = 6;
    public static final int MAL_IUT = 0x0400;
    public static final int MAL = 0xFFFFFFFF;
    private final byte mVersion;
    private final byte mField;
    private final int mLength;
    private final int mAcceptableLength;
    private final NdefMessage mNdefMessage;

    public static SnepMessage getGetRequest(int acceptableLength, NdefMessage ndef) {
        return new SnepMessage(VERSION, REQUEST_GET, 4 + ndef.toByteArray().length,
                acceptableLength, ndef);
    }

    public static SnepMessage getPutRequest(NdefMessage ndef) {
        return new SnepMessage(VERSION, REQUEST_PUT, ndef.toByteArray().length, 0, ndef);
    }

    public static SnepMessage getMessage(byte field) {
        return new SnepMessage(VERSION, field, 0, 0, null);
    }

    public static SnepMessage getSuccessResponse(NdefMessage ndef) {
        if (ndef == null) {
            return new SnepMessage(VERSION, RESPONSE_SUCCESS, 0, 0, null);
        } else {
            return new SnepMessage(VERSION, RESPONSE_SUCCESS, ndef.toByteArray().length, 0, ndef);
        }
    }

    public static SnepMessage fromByteArray(byte[] data) throws FormatException {
        return new SnepMessage(data);
    }

    public static NdefMessage getLargeNdef() throws UnsupportedEncodingException {
        String snepTestData2 = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus at"
                +" lorem nunc, ut venenatis quam. Etiam id dolor quam, at viverra dolor."
                +" Phasellus eu lacus ligula, quis euismod erat. Sed feugiat, ligula at"
                +" mollis aliquet, justo lacus condimentum eros, non tincidunt neque"
                +" ipsum eu risus. Sed adipiscing dui euismod tellus ullamcorper ornare."
                +" Phasellus mattis risus et lectus euismod eu fermentum sem cursus."
                +" Phasellus tristique consectetur mauris eu porttitor. Sed lobortis"
                +" porttitor orci.";
        String lang = "la";
        byte[] textBytes = snepTestData2.getBytes();
        byte[] langBytes = lang.getBytes("US-ASCII");
        int langLength = langBytes.length;
        int textLength = textBytes.length;

        byte[] payload = new byte[1 + langLength + textLength];
        payload[0] = (byte) langLength;

        System.arraycopy(langBytes, 0, payload, 1, langLength);
        System.arraycopy(textBytes, 0, payload, 1 + langLength, textLength);

        NdefRecord data2 = new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], payload);
        return new NdefMessage(new NdefRecord[]{data2});
    }

    public static NdefMessage getSmallNdef() throws UnsupportedEncodingException {
        String snepTestData1 = "Lorem ipsum dolor sit amet.";
        String lang = "la";
        byte[] textBytes = snepTestData1.getBytes();
        byte[] langBytes = lang.getBytes("US-ASCII");
        int langLength = langBytes.length;
        int textLength = textBytes.length;

        byte[] payload = new byte[1 + langLength + textLength];
        payload[0] = (byte) langLength;

        System.arraycopy(langBytes, 0, payload, 1, langLength);
        System.arraycopy(textBytes, 0, payload, 1 + langLength, textLength);

        NdefRecord data1 = new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], payload);
        return new NdefMessage(new NdefRecord[]{data1});
    }

    private SnepMessage(byte[] data) throws FormatException {
        ByteBuffer input = ByteBuffer.wrap(data);
        int ndefOffset;
        int ndefLength;

        mVersion = input.get();
        mField = input.get();
        mLength = input.getInt();
        if (mField == REQUEST_GET) {
            mAcceptableLength = input.getInt();
            ndefOffset = HEADER_LENGTH + 4;
            ndefLength = mLength - 4;
        } else {
            mAcceptableLength = -1;
            ndefOffset = HEADER_LENGTH;
            ndefLength = mLength;
        }

        if (ndefLength > 0) {
            byte[] bytes = new byte[ndefLength];
            System.arraycopy(data, ndefOffset, bytes, 0, ndefLength);
            mNdefMessage = new NdefMessage(bytes);
        } else {
            mNdefMessage = null;
        }
    }

    SnepMessage(byte version, byte field, int length, int acceptableLength,
            NdefMessage ndefMessage) {
        mVersion = version;
        mField = field;
        mLength = length;
        mAcceptableLength = acceptableLength;
        mNdefMessage = ndefMessage;
    }

    public byte[] toByteArray() {
        byte[] bytes;
        if (mNdefMessage != null) {
            if (NfcService.sIsDtaMode && DtaSnepClient.mTestCaseId != 0) {
               if (DtaSnepClient.mTestCaseId == 5 || DtaSnepClient.mTestCaseId == 6) {
                   bytes = mNdefMessage.toByteArray();
               } else {
                   if (NfcService.sIsShortRecordLayout) {
                       bytes = NDEF_SHORT_TEST_RECORD;
                   } else {
                       bytes = NDEF_TEST_RECORD;
                   }
               }
            } else {
                bytes = mNdefMessage.toByteArray();
            }
        } else {
            bytes = new byte[0];
        }

        ByteArrayOutputStream buffer;
        try {
            if (mField == REQUEST_GET) {
                buffer = new ByteArrayOutputStream(bytes.length + HEADER_LENGTH + 4);
            } else {
                buffer = new ByteArrayOutputStream(bytes.length + HEADER_LENGTH);
            }

            DataOutputStream output = new DataOutputStream(buffer);
            output.writeByte(mVersion);
            output.writeByte(mField);
            if (mField == REQUEST_GET) {
                output.writeInt(bytes.length + 4);
                output.writeInt(mAcceptableLength);
            } else {
                output.writeInt(bytes.length);
            }
            output.write(bytes);
        } catch(IOException e) {
            return null;
        }

        return buffer.toByteArray();
    }

    public NdefMessage getNdefMessage() {
        return mNdefMessage;
    }

    public byte getField() {
        return mField;
    }

    public byte getVersion() {
        return mVersion;
    }

    public int getLength() {
        return mLength;
    }

    public int getAcceptableLength() {
        if (mField != REQUEST_GET) {
            throw new UnsupportedOperationException(
                    "Acceptable Length only available on get request messages.");
        }
        return mAcceptableLength;
    }
}
