package com.android.nfc.beam;

import com.android.nfc.R;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.util.Log;

import java.io.File;

/**
 * @hide
 */
public class BeamStatusReceiver extends BroadcastReceiver {
    private static final boolean DBG = true;
    private static final String TAG = "BeamStatusReceiver";

    private static final String ACTION_HANDOVER_STARTED =
            "android.nfc.handover.intent.action.HANDOVER_STARTED";

    private static final String ACTION_TRANSFER_PROGRESS =
            "android.nfc.handover.intent.action.TRANSFER_PROGRESS";

    private static final String ACTION_TRANSFER_DONE =
            "android.nfc.handover.intent.action.TRANSFER_DONE";

    private static final String EXTRA_HANDOVER_DATA_LINK_TYPE =
            "android.nfc.handover.intent.extra.HANDOVER_DATA_LINK_TYPE";


    private static final String EXTRA_TRANSFER_PROGRESS =
            "android.nfc.handover.intent.extra.TRANSFER_PROGRESS";

    private static final String EXTRA_TRANSFER_URI =
            "android.nfc.handover.intent.extra.TRANSFER_URI";

    private static final String EXTRA_OBJECT_COUNT =
            "android.nfc.handover.intent.extra.OBJECT_COUNT";

    private static final String EXTRA_TRANSFER_STATUS =
            "android.nfc.handover.intent.extra.TRANSFER_STATUS";

    private static final String EXTRA_TRANSFER_MIMETYPE =
            "android.nfc.handover.intent.extra.TRANSFER_MIME_TYPE";

    private static final String ACTION_STOP_BLUETOOTH_TRANSFER =
            "android.btopp.intent.action.STOP_HANDOVER_TRANSFER";

    // FIXME: Needs to stay in sync with com.android.bluetooth.opp.Constants
    private static final int HANDOVER_TRANSFER_STATUS_SUCCESS = 0;
    private static final int HANDOVER_TRANSFER_STATUS_FAILURE = 1;

    // permission needed to be able to receive handover status requests
    public static final String BEAM_STATUS_PERMISSION =
            "android.permission.NFC_HANDOVER_STATUS";

    // Needed to build cancel intent in Beam notification
    public static final String EXTRA_INCOMING =
            "com.android.nfc.handover.extra.INCOMING";

    public static final String EXTRA_TRANSFER_ID =
            "android.nfc.handover.intent.extra.TRANSFER_ID";

    public static final String EXTRA_ADDRESS =
            "android.nfc.handover.intent.extra.ADDRESS";

    public static final String ACTION_CANCEL_HANDOVER_TRANSFER =
            "com.android.nfc.handover.action.CANCEL_HANDOVER_TRANSFER";

    public static final int DIRECTION_INCOMING = 0;
    public static final int DIRECTION_OUTGOING = 1;

    private final Context mContext;
    private final BeamTransferManager mTransferManager;

    BeamStatusReceiver(Context context, BeamTransferManager transferManager) {
        mContext = context;
        mTransferManager = transferManager;
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        int dataLinkType = intent.getIntExtra(EXTRA_HANDOVER_DATA_LINK_TYPE,
                BeamTransferManager.DATA_LINK_TYPE_BLUETOOTH);

        if (ACTION_CANCEL_HANDOVER_TRANSFER.equals(action)) {
            if (mTransferManager != null) {
                mTransferManager.cancel();
            }
        } else if (ACTION_TRANSFER_PROGRESS.equals(action) ||
                ACTION_TRANSFER_DONE.equals(action) ||
                ACTION_HANDOVER_STARTED.equals(action)) {
            handleTransferEvent(intent, dataLinkType);
        }
    }

    public IntentFilter getIntentFilter() {
        IntentFilter filter = new IntentFilter(ACTION_TRANSFER_DONE);
        filter.addAction(ACTION_TRANSFER_PROGRESS);
        filter.addAction(ACTION_CANCEL_HANDOVER_TRANSFER);
        filter.addAction(ACTION_HANDOVER_STARTED);
        return filter;
    }

    private void handleTransferEvent(Intent intent, int deviceType) {
        String action = intent.getAction();
        int id = intent.getIntExtra(EXTRA_TRANSFER_ID, -1);

        String sourceAddress = intent.getStringExtra(EXTRA_ADDRESS);

        if (sourceAddress == null) return;

        if (mTransferManager == null) {
            // There is no transfer running for this source address; most likely
            // the transfer was cancelled. We need to tell BT OPP to stop transferring.
            if (id != -1) {
                if (deviceType == BeamTransferManager.DATA_LINK_TYPE_BLUETOOTH) {
                    if (DBG) Log.d(TAG, "Didn't find transfer, stopping");
                    Intent cancelIntent = new Intent(ACTION_STOP_BLUETOOTH_TRANSFER);
                    cancelIntent.putExtra(EXTRA_TRANSFER_ID, id);
                    cancelIntent.setPackage(mContext.getString(R.string.bluetooth_package));
                    mContext.sendBroadcast(cancelIntent);
                }
            }
            return;
        }

        mTransferManager.setBluetoothTransferId(id);

        if (action.equals(ACTION_TRANSFER_DONE)) {
            int handoverStatus = intent.getIntExtra(EXTRA_TRANSFER_STATUS,
                    HANDOVER_TRANSFER_STATUS_FAILURE);
            if (handoverStatus == HANDOVER_TRANSFER_STATUS_SUCCESS) {
                String uriString = intent.getStringExtra(EXTRA_TRANSFER_URI);
                String mimeType = intent.getStringExtra(EXTRA_TRANSFER_MIMETYPE);
                Uri uri = Uri.parse(uriString);
                if (uri != null && uri.getScheme() == null) {
                    uri = Uri.fromFile(new File(uri.getPath()));
                }
                mTransferManager.finishTransfer(true, uri, mimeType);
            } else {
                mTransferManager.finishTransfer(false, null, null);
            }
        } else if (action.equals(ACTION_TRANSFER_PROGRESS)) {
            float progress = intent.getFloatExtra(EXTRA_TRANSFER_PROGRESS, 0.0f);
            mTransferManager.updateFileProgress(progress);
        } else if (action.equals(ACTION_HANDOVER_STARTED)) {
            int count = intent.getIntExtra(EXTRA_OBJECT_COUNT, 0);
            if (count > 0) {
                mTransferManager.setObjectCount(count);
            }
        }
    }
}
