/*
 *  Copyright (C) 2004-2014 Savoir-Faire Linux Inc.
 *
 *  Author: Alexandre Lision <alexandre.lision@savoirfairelinux.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *  Additional permission under GNU GPL version 3 section 7:
 *
 *  If you modify this program, or any covered work, by linking or
 *  combining it with the OpenSSL project's OpenSSL library (or a
 *  modified version of that library), containing parts covered by the
 *  terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
 *  grants you additional permission to convey the resulting work.
 *  Corresponding Source for a non-source form of such a combination
 *  shall include the source code for the parts of OpenSSL used as well
 *  as that of the covered work.
 */
package org.sflphone.receivers;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;

import org.sflphone.client.CallActivity;
import org.sflphone.model.Account;
import org.sflphone.model.CallContact;
import org.sflphone.model.Conference;
import org.sflphone.model.SipCall;
import org.sflphone.model.SipMessage;
import org.sflphone.service.CallManagerCallBack;
import org.sflphone.service.ConfigurationManagerCallback;
import org.sflphone.service.ISipService.Stub;
import org.sflphone.service.ServiceConstants;
import org.sflphone.service.SipService;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.RemoteException;
import android.util.Log;

public class IncomingReceiver extends BroadcastReceiver {

    static final String TAG = IncomingReceiver.class.getSimpleName();

    SipService callback;
    Stub mBinder;

    public IncomingReceiver(SipService client, Stub bind) {
        callback = client;
        mBinder = bind;
    }

    @SuppressWarnings("unchecked")
    // Hashmap runtime cast
    @Override
    public void onReceive(Context context, Intent intent) {

        if (intent.getAction().contentEquals(ConfigurationManagerCallback.ACCOUNT_STATE_CHANGED)) {

            Log.i(TAG, "Received" + intent.getAction());
            callback.sendBroadcast(intent);

        } else if (intent.getAction().contentEquals(ConfigurationManagerCallback.ACCOUNTS_CHANGED)) {

            Log.i(TAG, "Received" + intent.getAction());
            callback.sendBroadcast(intent);

        } else if (intent.getAction().contentEquals(CallManagerCallBack.INCOMING_TEXT)) {

            Bundle extra = intent.getBundleExtra("com.savoirfairelinux.sflphone.service.newtext");
            Log.i(TAG, "Received" + intent.getAction());
            if (callback.getCurrent_calls().get(extra.getString("CallID")) != null) {
                callback.getCurrent_calls().get(extra.get("CallID")).addSipMessage(new SipMessage(true, extra.getString("Msg")));
            } else if (callback.getCurrent_confs().get(extra.getString("CallID")) != null) {
                callback.getCurrent_confs().get(extra.get("CallID")).addSipMessage(new SipMessage(true, extra.getString("Msg")));
            } else
                return;

            callback.sendBroadcast(intent);

        } else if (intent.getAction().contentEquals(CallManagerCallBack.INCOMING_CALL)) {
            Bundle b = intent.getBundleExtra("com.savoirfairelinux.sflphone.service.newcall");

            SipCall.SipCallBuilder callBuilder = SipCall.SipCallBuilder.getInstance();

            Account acc;
            try {
                HashMap<String, String> details = (HashMap<String, String>) mBinder.getAccountDetails(b.getString("AccountID"));
                ArrayList<HashMap<String, String>> credentials = (ArrayList<HashMap<String, String>>) mBinder
                        .getCredentials(b.getString("AccountID"));
                acc = new Account(b.getString("AccountID"), details, credentials);
                callBuilder.startCallCreation(b.getString("CallID")).setAccount(acc).setCallState(SipCall.state.CALL_STATE_RINGING)
                        .setCallType(SipCall.state.CALL_TYPE_INCOMING);
                callBuilder.setContact(CallContact.ContactBuilder.buildUnknownContact(b.getString("From")));

                Intent toSend = new Intent(CallManagerCallBack.INCOMING_CALL);
                toSend.setClass(callback, CallActivity.class);
                toSend.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

                SipCall newCall = callBuilder.build();
                toSend.putExtra("newcall", newCall);
                HashMap<String, String> callDetails = (HashMap<String, String>) mBinder.getCallDetails(b.getString("CallID"));

                newCall.setTimestamp_start(Long.parseLong(callDetails.get(ServiceConstants.call.TIMESTAMP_START)));
                callback.getCurrent_calls().put(newCall.getCallId(), newCall);
                // callback.sendBroadcast(toSend);
                Bundle bundle = new Bundle();
                Conference tmp = new Conference("-1");

                tmp.getParticipants().add(newCall);

                bundle.putParcelable("conference", tmp);
                toSend.putExtra("resuming", false);
                toSend.putExtras(bundle);
                callback.startActivity(toSend);
                callback.mediaManager.startRing("");
                callback.mediaManager.obtainAudioFocus(true);
            } catch (RemoteException e1) {
                e1.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }

        } else if (intent.getAction().contentEquals(CallManagerCallBack.CALL_STATE_CHANGED)) {

            Log.i(TAG, "Received " + intent.getAction());
            Bundle b = intent.getBundleExtra("com.savoirfairelinux.sflphone.service.newstate");
            String newState = b.getString("State");

            try {
                if (callback.getCurrent_calls().get(b.getString("CallID")) != null && mBinder.isConferenceParticipant(b.getString("CallID"))) {
                    callback.getCurrent_calls().remove(b.getString("CallID"));
                }
            } catch (RemoteException e1) {
                e1.printStackTrace();
            }

            if (newState.equals("INCOMING")) {
                callback.getCurrent_calls().get(b.getString("CallID")).setCallState(SipCall.state.CALL_STATE_INCOMING);
            } else if (newState.equals("RINGING")) {
                try {
                    callback.getCurrent_calls().get(b.getString("CallID")).setCallState(SipCall.state.CALL_STATE_RINGING);
                } catch (NullPointerException e) {
                    if (callback.getCurrent_calls() == null) {
                        return;
                    }
                    if (callback.getCurrent_calls().get(b.getString("CallID")) == null) {
                        Log.e(TAG, "get(b.getString(callID)) null");
                        return;
                    }
                }

            } else if (newState.equals("CURRENT")) {
                if (callback.getCurrent_calls().get(b.getString("CallID")) != null) {
                    callback.getCurrent_calls().get(b.getString("CallID")).setCallState(SipCall.state.CALL_STATE_CURRENT);
                } else {
                    // Check if call is in a conference
                    Iterator<Entry<String, Conference>> it = callback.getCurrent_confs().entrySet().iterator();
                    while (it.hasNext()) {
                        Conference tmp = it.next().getValue();
                        for (SipCall c : tmp.getParticipants()) {
                            if (c.getCallId().contentEquals(b.getString("CallID")))
                                c.setCallState(SipCall.state.CALL_STATE_CURRENT);
                        }
                    }
                }

            } else if (newState.equals("HUNGUP")) {

                if (callback.getCurrent_calls().get(b.getString("CallID")) != null) {

                    if (callback.getCurrent_calls().get(b.getString("CallID")).isRinging()
                            && callback.getCurrent_calls().get(b.getString("CallID")).isIncoming())
                        callback.notificationManager.publishMissedCallNotification(callback.getCurrent_calls().get(b.getString("CallID")));
                    callback.getCurrent_calls().remove(b.getString("CallID"));
                } else {
                    ArrayList<Conference> it = new ArrayList<Conference>(callback.getCurrent_confs().values());

                    boolean found = false;
                    int i = 0;
                    while (!found && i < it.size()) {
                        Conference tmp = it.get(i);

                        for (int j = 0; j < tmp.getParticipants().size(); ++j) {
                            if (tmp.getParticipants().get(j).getCallId().contentEquals(b.getString("CallID"))) {
                                callback.getCurrent_confs().get(tmp.getId()).getParticipants().remove(tmp.getParticipants().get(j));
                                found = true;
                            }

                        }
                        ++i;

                    }
                }

                callback.sendBroadcast(intent);

            } else if (newState.equals("BUSY")) {
                callback.getCurrent_calls().remove(b.getString("CallID"));
            } else if (newState.equals("FAILURE")) {
                callback.getCurrent_calls().remove(b.getString("CallID"));
            } else if (newState.equals("HOLD")) {
                if (callback.getCurrent_calls().get(b.getString("CallID")) != null) {
                    callback.getCurrent_calls().get(b.getString("CallID")).setCallState(SipCall.state.CALL_STATE_HOLD);
                } else {
                    // Check if call is in a conference
                    Iterator<Entry<String, Conference>> it = callback.getCurrent_confs().entrySet().iterator();
                    while (it.hasNext()) {
                        Conference tmp = it.next().getValue();
                        for (SipCall c : tmp.getParticipants()) {
                            if (c.getCallId().contentEquals(b.getString("CallID")))
                                c.setCallState(SipCall.state.CALL_STATE_HOLD);
                        }
                    }
                }
            } else if (newState.equals("UNHOLD")) {

                if (callback.getCurrent_calls().get(b.getString("CallID")) != null) {
                    callback.getCurrent_calls().get(b.getString("CallID")).setCallState(SipCall.state.CALL_STATE_CURRENT);
                } else {
                    // Check if call is in a conference
                    Iterator<Entry<String, Conference>> it = callback.getCurrent_confs().entrySet().iterator();
                    while (it.hasNext()) {
                        Conference tmp = it.next().getValue();
                        for (SipCall c : tmp.getParticipants()) {
                            if (c.getCallId().contentEquals(b.getString("CallID")))
                                c.setCallState(SipCall.state.CALL_STATE_CURRENT);
                        }
                    }
                }
            } else {
                callback.getCurrent_calls().get(b.getString("CallID")).setCallState(SipCall.state.CALL_STATE_NONE);
            }

            callback.sendBroadcast(intent);

        } else if (intent.getAction().contentEquals(CallManagerCallBack.NEW_CALL_CREATED)) {

            Log.i(TAG, "Received" + intent.getAction());

        } else if (intent.getAction().contentEquals(CallManagerCallBack.CONF_CREATED)) {

            Log.i(TAG, "Received" + intent.getAction());
            Conference created = new Conference(intent.getStringExtra("confID"));

            try {
                ArrayList<String> all_participants = (ArrayList<String>) mBinder.getParticipantList(intent.getStringExtra("confID"));
                for (String participant : all_participants) {
                    created.getParticipants().add(callback.getCurrent_calls().get(participant));
                    callback.getCurrent_calls().remove(participant);
                }
                Intent toSend = new Intent(CallManagerCallBack.CONF_CREATED);
                toSend.putExtra("newconf", created);
                callback.getCurrent_confs().put(intent.getStringExtra("confID"), created);
                callback.sendBroadcast(toSend);
            } catch (RemoteException e1) {
                e1.printStackTrace();
            }
            Log.i(TAG, "current_confs size " + callback.getCurrent_confs().size());

        } else if (intent.getAction().contentEquals(CallManagerCallBack.CONF_REMOVED)) {

            Log.i(TAG, "Received" + intent.getAction());
            Conference toDestroy = callback.getCurrent_confs().get(intent.getStringExtra("confID"));
            for (int i = 0; i < toDestroy.getParticipants().size(); ++i) {
                callback.getCurrent_calls().put(toDestroy.getParticipants().get(i).getCallId(), toDestroy.getParticipants().get(i));
            }
            callback.getCurrent_confs().remove(intent.getStringExtra("confID"));
            callback.sendBroadcast(intent);

        } else if (intent.getAction().contentEquals(CallManagerCallBack.CONF_CHANGED)) {

            ArrayList<String> all_participants;
            try {
                all_participants = (ArrayList<String>) mBinder.getParticipantList(intent.getStringExtra("confID"));
                for (String participant : all_participants) {
                    if (callback.getCurrent_confs().get(intent.getStringExtra("confID")).getParticipants().size() < all_participants.size()
                            && callback.getCurrent_calls().get(participant) != null) { // We need to add the new participant to the conf
                        callback.getCurrent_confs().get(intent.getStringExtra("confID")).getParticipants()
                                .add(callback.getCurrent_calls().get(participant));
                        callback.getCurrent_calls().remove(participant);
                        callback.getCurrent_confs().get(intent.getStringExtra("confID")).setState(intent.getStringExtra("State"));
                        callback.sendBroadcast(intent);
                        return;
                    }
                }
            } catch (RemoteException e) {
                e.printStackTrace();
            }

            Log.i(TAG, "Received" + intent.getAction());
            if (callback.getCurrent_confs().get(intent.getStringExtra("confID")) != null) {

                callback.getCurrent_confs().get(intent.getStringExtra("confID")).setState(intent.getStringExtra("State"));
                callback.sendBroadcast(intent);
            }

        } else if (intent.getAction().contentEquals(CallManagerCallBack.RECORD_STATE_CHANGED)) {

            Log.i(TAG, "Received" + intent.getAction());

            // try {
            // if (callback.getCurrent_confs().get(intent.getStringExtra("id")) != null) {
            // callback.getCurrent_confs().get(intent.getStringExtra("id")).setRecording(mBinder.isRecording(intent.getStringExtra("id")));
            // } else if (callback.getCurrent_calls().get(intent.getStringExtra("id")) != null) {
            // callback.getCurrent_calls().get(intent.getStringExtra("id")).setRecording(mBinder.isRecording(intent.getStringExtra("id")));
            // } else {
            // // A call in a conference has been put on hold
            // Iterator<Conference> it = callback.getCurrent_confs().values().iterator();
            // while (it.hasNext()) {
            // Conference c = it.next();
            // if (c.getCall(intent.getStringExtra("id")) != null)
            // c.getCall(intent.getStringExtra("id")).setRecording(mBinder.isRecording(intent.getStringExtra("id")));
            // }
            // }
            // // Re sending the same intent to the app
            // callback.sendBroadcast(intent);
            // ;
            // } catch (RemoteException e) {
            // // TODO Auto-generated catch block
            // e.printStackTrace();
            // }

        }

    }
}
