/*
 * Copyright (c) 2008-2009, Motorola, Inc.
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * - Neither the name of the Motorola, Inc. nor the names of its contributors
 * may be used to endorse or promote products derived from this software
 * without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

package com.android.bluetooth.opp;

import android.content.ContentValues;
import android.content.Context;
import android.net.Uri;
import android.os.Handler;
import android.os.Message;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.os.Process;
import android.os.SystemClock;
import android.util.Log;

import com.android.bluetooth.BluetoothMetricsProto;
import com.android.bluetooth.btservice.MetricsLogger;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.obex.ClientOperation;
import javax.obex.ClientSession;
import javax.obex.HeaderSet;
import javax.obex.ObexTransport;
import javax.obex.ResponseCodes;

/**
 * This class runs as an OBEX client
 */
public class BluetoothOppObexClientSession implements BluetoothOppObexSession {

    private static final String TAG = "BtOppObexClient";
    private static final boolean D = Constants.DEBUG;
    private static final boolean V = Constants.VERBOSE;

    private ClientThread mThread;

    private ObexTransport mTransport;

    private Context mContext;

    private volatile boolean mInterrupted;

    private volatile boolean mWaitingForRemote;

    private Handler mCallback;

    private int mNumFilesAttemptedToSend;

    public BluetoothOppObexClientSession(Context context, ObexTransport transport) {
        if (transport == null) {
            throw new NullPointerException("transport is null");
        }
        mContext = context;
        mTransport = transport;
    }

    @Override
    public void start(Handler handler, int numShares) {
        if (D) {
            Log.d(TAG, "Start!");
        }
        mCallback = handler;
        mThread = new ClientThread(mContext, mTransport, numShares);
        mThread.start();
    }

    @Override
    public void stop() {
        if (D) {
            Log.d(TAG, "Stop!");
        }
        if (mThread != null) {
            mInterrupted = true;
            try {
                mThread.interrupt();
                if (V) {
                    Log.v(TAG, "waiting for thread to terminate");
                }
                mThread.join();
                mThread = null;
            } catch (InterruptedException e) {
                if (V) {
                    Log.v(TAG, "Interrupted waiting for thread to join");
                }
            }
        }
        BluetoothOppUtility.cancelNotification(mContext);
        mCallback = null;
    }

    @Override
    public void addShare(BluetoothOppShareInfo share) {
        mThread.addShare(share);
    }

    private static int readFully(InputStream is, byte[] buffer, int size) throws IOException {
        int done = 0;
        while (done < size) {
            int got = is.read(buffer, done, size - done);
            if (got <= 0) {
                break;
            }
            done += got;
        }
        return done;
    }

    private class ClientThread extends Thread {

        private static final int SLEEP_TIME = 500;

        private Context mContext1;

        private BluetoothOppShareInfo mInfo;

        private volatile boolean mWaitingForShare;

        private ObexTransport mTransport1;

        private ClientSession mCs;

        private WakeLock mWakeLock;

        private BluetoothOppSendFileInfo mFileInfo = null;

        private boolean mConnected = false;

        private int mNumShares;

        ClientThread(Context context, ObexTransport transport, int initialNumShares) {
            super("BtOpp ClientThread");
            mContext1 = context;
            mTransport1 = transport;
            mWaitingForShare = true;
            mWaitingForRemote = false;
            mNumShares = initialNumShares;
            PowerManager pm = (PowerManager) mContext1.getSystemService(Context.POWER_SERVICE);
            mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
        }

        public void addShare(BluetoothOppShareInfo info) {
            mInfo = info;
            mFileInfo = processShareInfo();
            mWaitingForShare = false;
        }

        @Override
        public void run() {
            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);

            if (V) {
                Log.v(TAG, "acquire partial WakeLock");
            }
            mWakeLock.acquire();

            try {
                Thread.sleep(100);
            } catch (InterruptedException e1) {
                if (V) {
                    Log.v(TAG, "Client thread was interrupted (1), exiting");
                }
                mInterrupted = true;
            }
            if (!mInterrupted) {
                connect(mNumShares);
            }

            mNumFilesAttemptedToSend = 0;
            while (!mInterrupted) {
                if (!mWaitingForShare) {
                    doSend();
                } else {
                    try {
                        if (D) {
                            Log.d(TAG, "Client thread waiting for next share, sleep for "
                                    + SLEEP_TIME);
                        }
                        Thread.sleep(SLEEP_TIME);
                    } catch (InterruptedException e) {

                    }
                }
            }
            disconnect();

            if (mWakeLock.isHeld()) {
                if (V) {
                    Log.v(TAG, "release partial WakeLock");
                }
                mWakeLock.release();
            }

            if (mNumFilesAttemptedToSend > 0) {
                // Log outgoing OPP transfer if more than one file is accepted by remote
                MetricsLogger.logProfileConnectionEvent(BluetoothMetricsProto.ProfileId.OPP);
            }
            Message msg = Message.obtain(mCallback);
            msg.what = BluetoothOppObexSession.MSG_SESSION_COMPLETE;
            msg.obj = mInfo;
            msg.sendToTarget();

        }

        private void disconnect() {
            try {
                if (mCs != null) {
                    mCs.disconnect(null);
                }
                mCs = null;
                if (D) {
                    Log.d(TAG, "OBEX session disconnected");
                }
            } catch (IOException e) {
                Log.w(TAG, "OBEX session disconnect error" + e);
            }
            try {
                if (mCs != null) {
                    if (D) {
                        Log.d(TAG, "OBEX session close mCs");
                    }
                    mCs.close();
                    if (D) {
                        Log.d(TAG, "OBEX session closed");
                    }
                }
            } catch (IOException e) {
                Log.w(TAG, "OBEX session close error" + e);
            }
            if (mTransport1 != null) {
                try {
                    mTransport1.close();
                } catch (IOException e) {
                    Log.e(TAG, "mTransport.close error");
                }

            }
        }

        private void connect(int numShares) {
            if (D) {
                Log.d(TAG, "Create ClientSession with transport " + mTransport1.toString());
            }
            try {
                mCs = new ClientSession(mTransport1);
                mConnected = true;
            } catch (IOException e1) {
                Log.e(TAG, "OBEX session create error");
            }
            if (mConnected) {
                mConnected = false;
                HeaderSet hs = new HeaderSet();
                hs.setHeader(HeaderSet.COUNT, (long) numShares);
                synchronized (this) {
                    mWaitingForRemote = true;
                }
                try {
                    mCs.connect(hs);
                    if (D) {
                        Log.d(TAG, "OBEX session created");
                    }
                    mConnected = true;
                } catch (IOException e) {
                    Log.e(TAG, "OBEX session connect error");
                }
            }
            synchronized (this) {
                mWaitingForRemote = false;
            }
        }

        private void doSend() {

            int status = BluetoothShare.STATUS_SUCCESS;

            /* connection is established too fast to get first mInfo */
            while (mFileInfo == null) {
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    status = BluetoothShare.STATUS_CANCELED;
                }
            }
            if (!mConnected) {
                // Obex connection error
                status = BluetoothShare.STATUS_CONNECTION_ERROR;
            }
            if (status == BluetoothShare.STATUS_SUCCESS) {
                /* do real send */
                if (mFileInfo.mFileName != null) {
                    status = sendFile(mFileInfo);
                } else {
                    /* this is invalid request */
                    status = mFileInfo.mStatus;
                }
                mWaitingForShare = true;
            } else {
                Constants.updateShareStatus(mContext1, mInfo.mId, status);
            }

            Message msg = Message.obtain(mCallback);
            msg.what = (status == BluetoothShare.STATUS_SUCCESS)
                    ? BluetoothOppObexSession.MSG_SHARE_COMPLETE
                    : BluetoothOppObexSession.MSG_SESSION_ERROR;
            mInfo.mStatus = status;
            msg.obj = mInfo;
            msg.sendToTarget();
        }

        /*
         * Validate this ShareInfo
         */
        private BluetoothOppSendFileInfo processShareInfo() {
            if (V) {
                Log.v(TAG, "Client thread processShareInfo() " + mInfo.mId);
            }

            BluetoothOppSendFileInfo fileInfo = BluetoothOppUtility.getSendFileInfo(mInfo.mUri);
            if (fileInfo.mFileName == null || fileInfo.mLength == 0) {
                if (V) {
                    Log.v(TAG, "BluetoothOppSendFileInfo get invalid file");
                }
                Constants.updateShareStatus(mContext1, mInfo.mId, fileInfo.mStatus);

            } else {
                if (V) {
                    Log.v(TAG, "Generate BluetoothOppSendFileInfo:");
                    Log.v(TAG, "filename  :" + fileInfo.mFileName);
                    Log.v(TAG, "length    :" + fileInfo.mLength);
                    Log.v(TAG, "mimetype  :" + fileInfo.mMimetype);
                }

                ContentValues updateValues = new ContentValues();
                Uri contentUri = Uri.parse(BluetoothShare.CONTENT_URI + "/" + mInfo.mId);

                updateValues.put(BluetoothShare.FILENAME_HINT, fileInfo.mFileName);
                updateValues.put(BluetoothShare.TOTAL_BYTES, fileInfo.mLength);
                updateValues.put(BluetoothShare.MIMETYPE, fileInfo.mMimetype);

                mContext1.getContentResolver().update(contentUri, updateValues, null, null);

            }
            return fileInfo;
        }

        private int sendFile(BluetoothOppSendFileInfo fileInfo) {
            boolean error = false;
            int responseCode = -1;
            long position = 0;
            int status = BluetoothShare.STATUS_SUCCESS;
            Uri contentUri = Uri.parse(BluetoothShare.CONTENT_URI + "/" + mInfo.mId);
            ContentValues updateValues;
            HeaderSet request = new HeaderSet();
            ClientOperation putOperation = null;
            OutputStream outputStream = null;
            InputStream inputStream = null;
            try {
                synchronized (this) {
                    mWaitingForRemote = true;
                }
                try {
                    if (V) {
                        Log.v(TAG, "Set header items for " + fileInfo.mFileName);
                    }
                    request.setHeader(HeaderSet.NAME, fileInfo.mFileName);
                    request.setHeader(HeaderSet.TYPE, fileInfo.mMimetype);

                    applyRemoteDeviceQuirks(request, mInfo.mDestination, fileInfo.mFileName);
                    Constants.updateShareStatus(mContext1, mInfo.mId,
                            BluetoothShare.STATUS_RUNNING);

                    request.setHeader(HeaderSet.LENGTH, fileInfo.mLength);

                    if (V) {
                        Log.v(TAG, "put headerset for " + fileInfo.mFileName);
                    }
                    putOperation = (ClientOperation) mCs.put(request);
                } catch (IllegalArgumentException e) {
                    status = BluetoothShare.STATUS_OBEX_DATA_ERROR;
                    Constants.updateShareStatus(mContext1, mInfo.mId, status);

                    Log.e(TAG, "Error setting header items for request: " + e);
                    error = true;
                } catch (IOException e) {
                    status = BluetoothShare.STATUS_OBEX_DATA_ERROR;
                    Constants.updateShareStatus(mContext1, mInfo.mId, status);

                    Log.e(TAG, "Error when put HeaderSet ");
                    error = true;
                }
                synchronized (this) {
                    mWaitingForRemote = false;
                }

                if (!error) {
                    try {
                        if (V) {
                            Log.v(TAG, "openOutputStream " + fileInfo.mFileName);
                        }
                        outputStream = putOperation.openOutputStream();
                        inputStream = putOperation.openInputStream();
                    } catch (IOException e) {
                        status = BluetoothShare.STATUS_OBEX_DATA_ERROR;
                        Constants.updateShareStatus(mContext1, mInfo.mId, status);
                        Log.e(TAG, "Error when openOutputStream");
                        error = true;
                    }
                }
                if (!error) {
                    updateValues = new ContentValues();
                    updateValues.put(BluetoothShare.CURRENT_BYTES, 0);
                    updateValues.put(BluetoothShare.STATUS, BluetoothShare.STATUS_RUNNING);
                    mContext1.getContentResolver().update(contentUri, updateValues, null, null);
                }

                if (!error) {
                    int readLength = 0;
                    long percent = 0;
                    long prevPercent = 0;
                    boolean okToProceed = false;
                    long timestamp = 0;
                    long currentTime = 0;
                    long prevTimestamp = SystemClock.elapsedRealtime();
                    int outputBufferSize = putOperation.getMaxPacketSize();
                    byte[] buffer = new byte[outputBufferSize];
                    BufferedInputStream a = new BufferedInputStream(fileInfo.mInputStream, 0x4000);

                    if (!mInterrupted && (position != fileInfo.mLength)) {
                        readLength = readFully(a, buffer, outputBufferSize);

                        mCallback.sendMessageDelayed(mCallback.obtainMessage(
                                BluetoothOppObexSession.MSG_CONNECT_TIMEOUT),
                                BluetoothOppObexSession.SESSION_TIMEOUT);
                        synchronized (this) {
                            mWaitingForRemote = true;
                        }

                        // first packet will block here
                        outputStream.write(buffer, 0, readLength);

                        position += readLength;

                        if (position == fileInfo.mLength) {
                            // if file length is smaller than buffer size, only one packet
                            // so block point is here
                            outputStream.close();
                            outputStream = null;
                        }

                        /* check remote accept or reject */
                        responseCode = putOperation.getResponseCode();

                        mCallback.removeMessages(BluetoothOppObexSession.MSG_CONNECT_TIMEOUT);
                        synchronized (this) {
                            mWaitingForRemote = false;
                        }

                        if (responseCode == ResponseCodes.OBEX_HTTP_CONTINUE
                                || responseCode == ResponseCodes.OBEX_HTTP_OK) {
                            if (V) {
                                Log.v(TAG, "Remote accept");
                            }
                            okToProceed = true;
                            updateValues = new ContentValues();
                            updateValues.put(BluetoothShare.CURRENT_BYTES, position);
                            mContext1.getContentResolver()
                                    .update(contentUri, updateValues, null, null);
                            mNumFilesAttemptedToSend++;
                        } else {
                            Log.i(TAG, "Remote reject, Response code is " + responseCode);
                        }
                    }

                    while (!mInterrupted && okToProceed && (position < fileInfo.mLength)) {
                        if (V) {
                            timestamp = SystemClock.elapsedRealtime();
                        }

                        readLength = a.read(buffer, 0, outputBufferSize);
                        outputStream.write(buffer, 0, readLength);

                        /* check remote abort */
                        responseCode = putOperation.getResponseCode();
                        if (V) {
                            Log.v(TAG, "Response code is " + responseCode);
                        }
                        if (responseCode != ResponseCodes.OBEX_HTTP_CONTINUE
                                && responseCode != ResponseCodes.OBEX_HTTP_OK) {
                            /* abort happens */
                            okToProceed = false;
                        } else {
                            position += readLength;
                            currentTime = SystemClock.elapsedRealtime();
                            if (V) {
                                Log.v(TAG, "Sending file position = " + position
                                        + " readLength " + readLength + " bytes took "
                                        + (currentTime - timestamp) + " ms");
                            }
                            // Update the Progress Bar only if there is change in percentage
                            // or once per a period to notify NFC of this transfer is still alive
                            percent = position * 100 / fileInfo.mLength;
                            if (percent > prevPercent
                                    || currentTime - prevTimestamp > Constants.NFC_ALIVE_CHECK_MS) {
                                updateValues = new ContentValues();
                                updateValues.put(BluetoothShare.CURRENT_BYTES, position);
                                mContext1.getContentResolver()
                                        .update(contentUri, updateValues, null, null);
                                prevPercent = percent;
                                prevTimestamp = currentTime;
                            }
                        }
                    }

                    if (responseCode == ResponseCodes.OBEX_HTTP_FORBIDDEN
                            || responseCode == ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE) {
                        Log.i(TAG, "Remote reject file " + fileInfo.mFileName + " length "
                                + fileInfo.mLength);
                        status = BluetoothShare.STATUS_FORBIDDEN;
                    } else if (responseCode == ResponseCodes.OBEX_HTTP_UNSUPPORTED_TYPE) {
                        Log.i(TAG, "Remote reject file type " + fileInfo.mMimetype);
                        status = BluetoothShare.STATUS_NOT_ACCEPTABLE;
                    } else if (!mInterrupted && position == fileInfo.mLength) {
                        Log.i(TAG,
                                "SendFile finished send out file " + fileInfo.mFileName + " length "
                                        + fileInfo.mLength);
                    } else {
                        error = true;
                        status = BluetoothShare.STATUS_CANCELED;
                        putOperation.abort();
                        /* interrupted */
                        Log.i(TAG, "SendFile interrupted when send out file " + fileInfo.mFileName
                                + " at " + position + " of " + fileInfo.mLength);
                    }
                }
            } catch (IOException e) {
                handleSendException(e.toString());
            } catch (NullPointerException e) {
                handleSendException(e.toString());
            } catch (IndexOutOfBoundsException e) {
                handleSendException(e.toString());
            } finally {
                try {
                    if (outputStream != null) {
                        outputStream.close();
                    }
                } catch (IOException e) {
                    Log.e(TAG, "Error when closing output stream after send");
                }

                // Close InputStream and remove SendFileInfo from map
                BluetoothOppUtility.closeSendFileInfo(mInfo.mUri);
                try {
                    if (!error) {
                        responseCode = putOperation.getResponseCode();
                        if (responseCode != -1) {
                            if (V) {
                                Log.v(TAG, "Get response code " + responseCode);
                            }
                            if (responseCode != ResponseCodes.OBEX_HTTP_OK) {
                                Log.i(TAG, "Response error code is " + responseCode);
                                status = BluetoothShare.STATUS_UNHANDLED_OBEX_CODE;
                                if (responseCode == ResponseCodes.OBEX_HTTP_UNSUPPORTED_TYPE) {
                                    status = BluetoothShare.STATUS_NOT_ACCEPTABLE;
                                }
                                if (responseCode == ResponseCodes.OBEX_HTTP_FORBIDDEN
                                        || responseCode == ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE) {
                                    status = BluetoothShare.STATUS_FORBIDDEN;
                                }
                            }
                        } else {
                            // responseCode is -1, which means connection error
                            status = BluetoothShare.STATUS_CONNECTION_ERROR;
                        }
                    }

                    Constants.updateShareStatus(mContext1, mInfo.mId, status);

                    if (inputStream != null) {
                        inputStream.close();
                    }
                    if (putOperation != null) {
                        putOperation.close();
                    }
                } catch (IOException e) {
                    Log.e(TAG, "Error when closing stream after send");

                    // Socket has been closed due to the response timeout in the framework,
                    // mark the transfer as failure.
                    if (position != fileInfo.mLength) {
                        status = BluetoothShare.STATUS_FORBIDDEN;
                        Constants.updateShareStatus(mContext1, mInfo.mId, status);
                    }
                }
            }
            BluetoothOppUtility.cancelNotification(mContext);
            return status;
        }

        private void handleSendException(String exception) {
            Log.e(TAG, "Error when sending file: " + exception);
            // Update interrupted outbound content resolver entry when
            // error during transfer.
            Constants.updateShareStatus(mContext1, mInfo.mId,
                    BluetoothShare.STATUS_OBEX_DATA_ERROR);
            mCallback.removeMessages(BluetoothOppObexSession.MSG_CONNECT_TIMEOUT);
        }

        @Override
        public void interrupt() {
            super.interrupt();
            synchronized (this) {
                if (mWaitingForRemote) {
                    if (V) {
                        Log.v(TAG, "Interrupted when waitingForRemote");
                    }
                    try {
                        mTransport1.close();
                    } catch (IOException e) {
                        Log.e(TAG, "mTransport.close error");
                    }
                    Message msg = Message.obtain(mCallback);
                    msg.what = BluetoothOppObexSession.MSG_SHARE_INTERRUPTED;
                    if (mInfo != null) {
                        msg.obj = mInfo;
                    }
                    msg.sendToTarget();
                }
            }
        }
    }

    public static void applyRemoteDeviceQuirks(HeaderSet request, String address, String filename) {
        if (address == null) {
            return;
        }
        if (address.startsWith("00:04:48")) {
            // Poloroid Pogo
            // Rejects filenames with more than one '.'. Rename to '_'.
            // for example: 'a.b.jpg' -> 'a_b.jpg'
            //              'abc.jpg' NOT CHANGED
            char[] c = filename.toCharArray();
            boolean firstDot = true;
            boolean modified = false;
            for (int i = c.length - 1; i >= 0; i--) {
                if (c[i] == '.') {
                    if (!firstDot) {
                        modified = true;
                        c[i] = '_';
                    }
                    firstDot = false;
                }
            }

            if (modified) {
                String newFilename = new String(c);
                request.setHeader(HeaderSet.NAME, newFilename);
                Log.i(TAG, "Sending file \"" + filename + "\" as \"" + newFilename
                        + "\" to workaround Poloroid filename quirk");
            }
        }
    }

    @Override
    public void unblock() {
        // Not used for client case
    }

}
