/*
 * Copyright (C) 2012 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.handover;

import com.android.nfc.DeviceHost.LlcpServerSocket;
import com.android.nfc.DeviceHost.LlcpSocket;
import com.android.nfc.LlcpException;
import com.android.nfc.NfcService;
import com.android.nfc.beam.BeamManager;
import com.android.nfc.beam.BeamReceiveService;
import com.android.nfc.beam.BeamTransferRecord;

import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.content.Intent;
import android.nfc.FormatException;
import android.nfc.NdefMessage;
import android.os.UserHandle;
import android.util.Log;

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

public final class HandoverServer {
    static final String HANDOVER_SERVICE_NAME = "urn:nfc:sn:handover";
    static final String TAG = "HandoverServer";
    static final Boolean DBG = false;

    static final int MIU = 128;

    final HandoverDataParser mHandoverDataParser;
    final int mSap;
    final Callback mCallback;
    private final Context mContext;

    ServerThread mServerThread = null;
    boolean mServerRunning = false;

    public interface Callback {
        void onHandoverRequestReceived();
        void onHandoverBusy();
    }

    public HandoverServer(Context context, int sap, HandoverDataParser manager, Callback callback) {
        mContext = context;
        mSap = sap;
        mHandoverDataParser = manager;
        mCallback = callback;
    }

    public synchronized void start() {
        if (mServerThread == null) {
            mServerThread = new ServerThread();
            mServerThread.start();
            mServerRunning = true;
        }
    }

    public synchronized void stop() {
        if (mServerThread != null) {
            mServerThread.shutdown();
            mServerThread = null;
            mServerRunning = false;
        }
    }

    private class ServerThread extends Thread {
        private boolean mThreadRunning = true;
        LlcpServerSocket mServerSocket;

        @Override
        public void run() {
            boolean threadRunning;
            synchronized (HandoverServer.this) {
                threadRunning = mThreadRunning;
            }

            while (threadRunning) {
                try {
                    synchronized (HandoverServer.this) {
                        mServerSocket = NfcService.getInstance().createLlcpServerSocket(mSap,
                                HANDOVER_SERVICE_NAME, MIU, 1, 1024);
                    }
                    if (mServerSocket == null) {
                        if (DBG) Log.d(TAG, "failed to create LLCP service socket");
                        return;
                    }
                    if (DBG) Log.d(TAG, "created LLCP service socket");
                    synchronized (HandoverServer.this) {
                        threadRunning = mThreadRunning;
                    }

                    while (threadRunning) {
                        LlcpServerSocket serverSocket;
                        synchronized (HandoverServer.this) {
                            serverSocket = mServerSocket;
                        }

                        if (serverSocket == null) {
                            if (DBG) Log.d(TAG, "Server socket shut down.");
                            return;
                        }
                        if (DBG) Log.d(TAG, "about to accept");
                        LlcpSocket communicationSocket = serverSocket.accept();
                        if (DBG) Log.d(TAG, "accept returned " + communicationSocket);
                        if (communicationSocket != null) {
                            new ConnectionThread(communicationSocket).start();
                        }

                        synchronized (HandoverServer.this) {
                            threadRunning = mThreadRunning;
                        }
                    }
                    if (DBG) Log.d(TAG, "stop running");
                } catch (LlcpException e) {
                    Log.e(TAG, "llcp error", e);
                } catch (IOException e) {
                    if (DBG) Log.d(TAG, "IO error");
                } finally {
                    synchronized (HandoverServer.this) {
                        if (mServerSocket != null) {
                            if (DBG) Log.d(TAG, "about to close");
                            try {
                                mServerSocket.close();
                            } catch (IOException e) {
                                // ignore
                            }
                            mServerSocket = null;
                        }
                    }
                }

                synchronized (HandoverServer.this) {
                    threadRunning = mThreadRunning;
                }
            }
        }

        public void shutdown() {
            synchronized (HandoverServer.this) {
                mThreadRunning = false;
                if (mServerSocket != null) {
                    try {
                        mServerSocket.close();
                    } catch (IOException e) {
                        // ignore
                    }
                    mServerSocket = null;
                }
            }
        }
    }

    private class ConnectionThread extends Thread {
        private final LlcpSocket mSock;

        ConnectionThread(LlcpSocket socket) {
            super(TAG);
            mSock = socket;
        }

        @Override
        public void run() {
            if (DBG) Log.d(TAG, "starting connection thread");
            ByteArrayOutputStream byteStream = new ByteArrayOutputStream();

            try {
                boolean running;
                synchronized (HandoverServer.this) {
                    running = mServerRunning;
                }

                byte[] partial = new byte[mSock.getLocalMiu()];

                NdefMessage handoverRequestMsg = null;
                while (running) {
                    int size = mSock.receive(partial);
                    if (size < 0) {
                        break;
                    }
                    byteStream.write(partial, 0, size);
                    // 1) Try to parse a handover request message from bytes received so far
                    try {
                        handoverRequestMsg = new NdefMessage(byteStream.toByteArray());
                    } catch (FormatException e) {
                        // Ignore, and try to fetch more bytes
                    }

                    if (handoverRequestMsg != null) {
                        BeamManager beamManager = BeamManager.getInstance();

                        if (beamManager.isBeamInProgress()) {
                            mCallback.onHandoverBusy();
                            break;
                        }

                        // 2) convert to handover response
                        HandoverDataParser.IncomingHandoverData handoverData
                                = mHandoverDataParser.getIncomingHandoverData(handoverRequestMsg);
                        if (handoverData == null) {
                            Log.e(TAG, "Failed to create handover response");
                            break;
                        }

                        // 3) send handover response
                        int offset = 0;
                        byte[] buffer = handoverData.handoverSelect.toByteArray();
                        int remoteMiu = mSock.getRemoteMiu();
                        while (offset < buffer.length) {
                            int length = Math.min(buffer.length - offset, remoteMiu);
                            byte[] tmpBuffer = Arrays.copyOfRange(buffer, offset, offset+length);
                            mSock.send(tmpBuffer);
                            offset += length;
                        }
                        // We're done
                        mCallback.onHandoverRequestReceived();
                        if (!beamManager.startBeamReceive(mContext, handoverData.handoverData)) {
                            mCallback.onHandoverBusy();
                            break;
                        }
                        // We can process another handover transfer
                        byteStream = new ByteArrayOutputStream();
                    }

                    synchronized (HandoverServer.this) {
                        running = mServerRunning;
                    }
                }

            } catch (IOException e) {
                if (DBG) Log.d(TAG, "IOException");
            } finally {
                try {
                    if (DBG) Log.d(TAG, "about to close");
                    mSock.close();
                } catch (IOException e) {
                    // ignore
                }
                try {
                    byteStream.close();
                } catch (IOException e) {
                    // ignore
                }
            }
            if (DBG) Log.d(TAG, "finished connection thread");
        }
    }
}

