/*
 * 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 com.android.nfc.DeviceHost.LlcpSocket;
import com.android.nfc.NfcService;
import com.android.nfc.sneptest.DtaSnepClient;
import com.android.nfc.sneptest.ExtDtaSnepServer;

import android.nfc.FormatException;
import android.util.Log;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.util.Arrays;

public class SnepMessenger {
    private static final String TAG = "SnepMessager";
    private static final boolean DBG = false;
    private static final int HEADER_LENGTH = 6;
    final LlcpSocket mSocket;
    final int mFragmentLength;
    final boolean mIsClient;

    public SnepMessenger(boolean isClient, LlcpSocket socket, int fragmentLength) {
        mSocket = socket;
        mFragmentLength = fragmentLength;
        mIsClient = isClient;
    }

    public void sendMessage(SnepMessage msg) throws IOException {
        byte[] buffer = msg.toByteArray();
        byte remoteContinue;
        if (mIsClient) {
            remoteContinue = SnepMessage.RESPONSE_CONTINUE;
        } else {
            remoteContinue = SnepMessage.REQUEST_CONTINUE;
        }
        if (DBG) Log.d(TAG, "about to send a " + buffer.length + " byte message");

        // Send first fragment
        int length = Math.min(buffer.length, mFragmentLength);
        byte[] tmpBuffer = Arrays.copyOfRange(buffer, 0, length);
        if (DBG) Log.d(TAG, "about to send a " + length + " byte fragment");
        mSocket.send(tmpBuffer);

        if (length == buffer.length) {
            return;
        }

        // Look for Continue or Reject from peer.
        int offset = length;
        byte[] responseBytes = new byte[HEADER_LENGTH];
        mSocket.receive(responseBytes);
        SnepMessage snepResponse;
        try {
            snepResponse = SnepMessage.fromByteArray(responseBytes);
        } catch (FormatException e) {
            throw new IOException("Invalid SNEP message", e);
        }

        if (DBG) Log.d(TAG, "Got response from first fragment: " + snepResponse.getField());
        if (snepResponse.getField() != remoteContinue) {
            throw new IOException("Invalid response from server (" +
                    snepResponse.getField() + ")");
        }
        // Look for wrong/invalid request or response from peer
       if (NfcService.sIsDtaMode) {
            if (mIsClient && (DtaSnepClient.mTestCaseId == 6)) {
                length = Math.min(buffer.length - offset, mFragmentLength);
                tmpBuffer = Arrays.copyOfRange(buffer, offset, offset + length);
                if (DBG) Log.d(TAG, "about to send a " + length + " byte fragment");
                mSocket.send(tmpBuffer);
                offset += length;

                mSocket.receive(responseBytes);

                try {
                    snepResponse = SnepMessage.fromByteArray(responseBytes);
                } catch (FormatException e) {
                    throw new IOException("Invalid SNEP message", e);
                }
                if (DBG) Log.d(TAG, "Got response from second fragment: " + snepResponse.getField());
                if (snepResponse.getField() == remoteContinue) {
                    close();
                    return;
                }
            }
        }

        // Send remaining fragments.
        while (offset < buffer.length) {
            length = Math.min(buffer.length - offset, mFragmentLength);
            tmpBuffer = Arrays.copyOfRange(buffer, offset, offset + length);
            if (DBG) Log.d(TAG, "about to send a " + length + " byte fragment");
            mSocket.send(tmpBuffer);

            if (NfcService.sIsDtaMode) {
                if (!mIsClient && ExtDtaSnepServer.mTestCaseId == 0x01) {
                    mSocket.receive(responseBytes);
                    try {
                        snepResponse = SnepMessage.fromByteArray(responseBytes);
                    } catch (FormatException e) {
                        throw new IOException("Invalid SNEP message", e);
                    }
                    if (DBG) Log.d(TAG, "Got continue response after second fragment: and now disconnecting..." + snepResponse.getField());
                    if (snepResponse.getField() == remoteContinue) {
                        close();
                        return;
                    }
                }
            }

            offset += length;
        }
    }

    public SnepMessage getMessage() throws IOException, SnepException {
        ByteArrayOutputStream buffer = new ByteArrayOutputStream(mFragmentLength);
        byte[] partial = new byte[mFragmentLength];
        int size;
        int requestSize = 0;
        int readSize = 0;
        byte requestVersion = 0;
        byte requestField = 0; // for DTA Mode
        boolean doneReading = false;
        byte fieldContinue;
        byte fieldReject;
        if (mIsClient) {
            fieldContinue = SnepMessage.REQUEST_CONTINUE;
            fieldReject = SnepMessage.REQUEST_REJECT;
        } else {
            fieldContinue = SnepMessage.RESPONSE_CONTINUE;
            fieldReject = SnepMessage.RESPONSE_REJECT;
        }

        size = mSocket.receive(partial);
        if (DBG) Log.d(TAG, "read " + size + " bytes");
        if (size < 0) {
            try {
                mSocket.send(SnepMessage.getMessage(fieldReject).toByteArray());
            } catch (IOException e) {
                // Ignore
            }
            throw new IOException("Error reading SNEP message.");
        } else if (size < HEADER_LENGTH) {
            try {
                if (NfcService.sIsDtaMode && mIsClient) {
                    if (DBG) Log.d(TAG, "Invalid header length");
                    close();
                } else {
                    mSocket.send(SnepMessage.getMessage(fieldReject).toByteArray());

                }
                mSocket.send(SnepMessage.getMessage(fieldReject).toByteArray());
            } catch (IOException e) {
                // Ignore
            }
            throw new IOException("Invalid fragment from sender.");
        } else {
            readSize = size - HEADER_LENGTH;
            buffer.write(partial, 0, size);
        }

        DataInputStream dataIn = new DataInputStream(new ByteArrayInputStream(partial));
        requestVersion = dataIn.readByte();
        requestField = dataIn.readByte();
        requestSize = dataIn.readInt();

        if (DBG) Log.d(TAG, "read " + readSize + " of " + requestSize);

        if (((requestVersion & 0xF0) >> 4) != SnepMessage.VERSION_MAJOR) {
            if (NfcService.sIsDtaMode) {
                sendMessage(SnepMessage.getMessage(SnepMessage.RESPONSE_UNSUPPORTED_VERSION));
                close();
            } else {
            if (NfcService.sIsDtaMode) {
                sendMessage(SnepMessage.getMessage(SnepMessage.RESPONSE_UNSUPPORTED_VERSION));
                close();
            } else {
                // Invalid protocol version; treat message as complete.
                return new SnepMessage(requestVersion, requestField, 0, 0, null);
            }
            }

        }

        if (NfcService.sIsDtaMode) {
            if (!mIsClient && (requestField == SnepMessage.RESPONSE_CONTINUE)||  // added for TC_S_BIT_B1_01_X
                              requestField == SnepMessage.RESPONSE_SUCCESS ||
                              requestField == SnepMessage.RESPONSE_NOT_FOUND) {
                if (DBG) Log.d(TAG, "errorneous response received, disconnecting client");
                close();
            }
            if (!mIsClient && requestField == SnepMessage.REQUEST_RFU) {
                if (DBG) Log.d(TAG, "unknown request received, disconnecting client");
                sendMessage(SnepMessage.getMessage(SnepMessage.RESPONSE_BAD_REQUEST));
                close();
            }
            // added for TC_C_BIT_BI_01_0
            if (mIsClient && requestField == SnepMessage.REQUEST_PUT) {
                if (DBG) Log.d(TAG, "errorneous PUT request received, disconnecting from server");
                    close();
            }
            // added for TC_C_GET_BV_03
            if (mIsClient && (requestSize > SnepMessage.MAL_IUT)) {
                if (DBG) Log.d(TAG, "responding reject");
                    return new SnepMessage(requestVersion, requestField, requestSize, 0, null);
            }
            //added for TC_S_ACC_BV_05_0&1 and TC_S_ACC_BV_06_0&1
            if (!mIsClient && ((requestSize > SnepMessage.MAL_IUT) ||
                                requestSize == SnepMessage.MAL)) {
                if (DBG) Log.d(TAG, "responding reject");
                    return new SnepMessage(requestVersion, requestField, requestSize, 0, null);
            }
        }

        if (requestSize > readSize) {
            if (DBG) Log.d(TAG, "requesting continuation");
            mSocket.send(SnepMessage.getMessage(fieldContinue).toByteArray());
        } else {
            doneReading = true;
        }

        // Remaining fragments
        while (!doneReading) {
            try {
                size = mSocket.receive(partial);
                if (DBG) Log.d(TAG, "read " + size + " bytes");
                if (size < 0) {
                    try {
                        mSocket.send(SnepMessage.getMessage(fieldReject).toByteArray());
                    } catch (IOException e) {
                        // Ignore
                    }
                    throw new IOException();
                } else {
                    readSize += size;
                    buffer.write(partial, 0, size);
                    if (readSize == requestSize) {
                        doneReading = true;
                    }
                }
            } catch (IOException e) {
                try {
                    mSocket.send(SnepMessage.getMessage(fieldReject).toByteArray());
                } catch (IOException e2) {
                    // Ignore
                }
                throw e;
            }
        }

        // Build NDEF message set from the stream
        try {
            return SnepMessage.fromByteArray(buffer.toByteArray());
        } catch (FormatException e) {
            Log.e(TAG, "Badly formatted NDEF message, ignoring", e);
            throw new SnepException(e);
        }
    }

    public void close() throws IOException {
        mSocket.close();
    }
}
