/*
* Copyright (C) 2015 Samsung System LSI
* 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.bluetooth;

import android.bluetooth.BluetoothSocket;
import android.os.Handler;
import android.os.Handler.Callback;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.util.Log;

import java.io.IOException;

import javax.obex.HeaderSet;
import javax.obex.ServerRequestHandler;

/**
 * A simple ObexServer used to handle connection rejection in two cases:
 *  - A profile cannot handle a new connection, as it is already connected to another device.
 *  - The user rejected access to the resources needed by the profile.
 *
 * Will reject the OBEX connection, start a timer, and at timeout close the socket.
 */
public class ObexRejectServer extends ServerRequestHandler implements Callback {

    private static final String TAG = "ObexRejectServer";
    private static final boolean V = true;
    private final int mResult;
    private final HandlerThread mHandlerThread;
    private final Handler mMessageHandler;
    private static final int MSG_ID_TIMEOUT = 0x01;
    private static final int TIMEOUT_VALUE = 5 * 1000; // ms
    private final BluetoothSocket mSocket;

    /**
     * @param result the ResponseCodes.OBEX_HTTP_ code to respond to an incoming connect request.
     */
    public ObexRejectServer(int result, BluetoothSocket socket) {
        super();
        mResult = result;
        mSocket = socket;
        mHandlerThread = new HandlerThread("TestTimeoutHandler",
                android.os.Process.THREAD_PRIORITY_BACKGROUND);
        mHandlerThread.start();
        Looper timeoutLooper = mHandlerThread.getLooper();
        mMessageHandler = new Handler(timeoutLooper, this);
        // Initiate self destruction.
        mMessageHandler.sendEmptyMessageDelayed(MSG_ID_TIMEOUT, TIMEOUT_VALUE);
    }

    // OBEX operation handlers
    @Override
    public int onConnect(HeaderSet request, HeaderSet reply) {
        if (V) {
            Log.i(TAG, "onConnect() returning error");
        }
        return mResult;
    }

    public void shutdown() {
        mMessageHandler.removeCallbacksAndMessages(null);
        mHandlerThread.quit();
        try {
            // This will cause an exception in the ServerSession, causing it to shut down
            mSocket.close();
        } catch (IOException e) {
            Log.w(TAG, "Unable to close socket - ignoring", e);
        }
    }

    @Override
    public boolean handleMessage(Message msg) {
        if (V) {
            Log.i(TAG, "Handling message ID: " + msg.what);
        }
        switch (msg.what) {
            case MSG_ID_TIMEOUT:
                shutdown();
                break;
            default:
                // Message not handled
                return false;
        }
        return true; // Message handled
    }
}
