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

import com.android.nfc.DeviceHost.LlcpServerSocket;
import com.android.nfc.DeviceHost.LlcpSocket;
import com.android.nfc.LlcpException;
import com.android.nfc.NfcService;

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

import java.io.ByteArrayOutputStream;
import java.io.IOException;

/**
 * A simple server that accepts NDEF messages pushed to it over an LLCP connection. Those messages
 * are typically set on the client side by using {@link NfcAdapter#enableForegroundNdefPush}.
 */
public class NdefPushServer {
    private static final String TAG = "NdefPushServer";
    private static final boolean DBG = true;

    private static final int MIU = 248;

    int mSap;

    static final String SERVICE_NAME = "com.android.npp";

    NfcService mService = NfcService.getInstance();

    final Callback mCallback;

    /** Protected by 'this', null when stopped, non-null when running */
    ServerThread mServerThread = null;

    public interface Callback {
        void onMessageReceived(NdefMessage msg);
    }

    public NdefPushServer(final int sap, Callback callback) {
        mSap = sap;
        mCallback = callback;
    }

    /** Connection class, used to handle incoming connections */
    private class ConnectionThread extends Thread {
        private LlcpSocket mSock;

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

        @Override
        public void run() {
            if (DBG) Log.d(TAG, "starting connection thread");
            try {
                ByteArrayOutputStream buffer = new ByteArrayOutputStream(1024);
                byte[] partial = new byte[1024];
                int size;
                boolean connectionBroken = false;

                // Get raw data from remote server
                while(!connectionBroken) {
                    try {
                        size = mSock.receive(partial);
                        if (DBG) Log.d(TAG, "read " + size + " bytes");
                        if (size < 0) {
                            connectionBroken = true;
                            break;
                        } else {
                            buffer.write(partial, 0, size);
                        }
                    } catch (IOException e) {
                        // Connection broken
                        connectionBroken = true;
                        if (DBG) Log.d(TAG, "connection broken by IOException", e);
                    }
                }

                // Build NDEF message set from the stream
                NdefPushProtocol msg = new NdefPushProtocol(buffer.toByteArray());
                if (DBG) Log.d(TAG, "got message " + msg.toString());

                // Send the intent for the fake tag
                mCallback.onMessageReceived(msg.getImmediate());
            } catch (FormatException e) {
                Log.e(TAG, "badly formatted NDEF message, ignoring", e);
            } finally {
                try {
                    if (DBG) Log.d(TAG, "about to close");
                    mSock.close();
                } catch (IOException e) {
                    // ignore
                }
            }
            if (DBG) Log.d(TAG, "finished connection thread");
        }
    }

    /** Server class, used to listen for incoming connection request */
    class ServerThread extends Thread {
        // Variables below synchronized on NdefPushServer.this
        boolean mRunning = true;
        LlcpServerSocket mServerSocket;

        @Override
        public void run() {
            boolean threadRunning;
            synchronized (NdefPushServer.this) {
                threadRunning = mRunning;
            }
            while (threadRunning) {
                if (DBG) Log.d(TAG, "about create LLCP service socket");
                try {
                    synchronized (NdefPushServer.this) {
                        mServerSocket = mService.createLlcpServerSocket(mSap, 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 (NdefPushServer.this) {
                        threadRunning = mRunning;
                    }

                    while (threadRunning) {
                        LlcpServerSocket serverSocket;
                        synchronized (NdefPushServer.this) {
                            serverSocket = mServerSocket;
                        }
                        if (serverSocket == null) 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 (NdefPushServer.this) {
                            threadRunning = mRunning;
                        }
                    }
                    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 (NdefPushServer.this) {
                        if (mServerSocket != null) {
                            if (DBG) Log.d(TAG, "about to close");
                            try {
                                mServerSocket.close();
                            } catch (IOException e) {
                                // ignore
                            }
                            mServerSocket = null;
                        }
                    }
                }

                synchronized (NdefPushServer.this) {
                    threadRunning = mRunning;
                }
            }
        }

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

    public void start() {
        synchronized (this) {
            if (DBG) Log.d(TAG, "start, thread = " + mServerThread);
            if (mServerThread == null) {
                if (DBG) Log.d(TAG, "starting new server thread");
                mServerThread = new ServerThread();
                mServerThread.start();
            }
        }
    }

    public void stop() {
        synchronized (this) {
            if (DBG) Log.d(TAG, "stop, thread = " + mServerThread);
            if (mServerThread != null) {
                if (DBG) Log.d(TAG, "shuting down server thread");
                mServerThread.shutdown();
                mServerThread = null;
            }
        }
    }
}
