package com.xtremelabs.robolectric.shadows;

import android.app.Application;
import android.appwidget.AppWidgetManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.res.Resources;
import android.os.IBinder;
import android.os.Looper;
import android.view.LayoutInflater;
import android.widget.Toast;
import com.xtremelabs.robolectric.Robolectric;
import com.xtremelabs.robolectric.internal.Implementation;
import com.xtremelabs.robolectric.internal.Implements;
import com.xtremelabs.robolectric.internal.RealObject;
import com.xtremelabs.robolectric.res.ResourceLoader;
import com.xtremelabs.robolectric.tester.org.apache.http.FakeHttpLayer;
import com.xtremelabs.robolectric.util.Scheduler;

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

import static com.xtremelabs.robolectric.Robolectric.newInstanceOf;
import static com.xtremelabs.robolectric.Robolectric.shadowOf;

/**
 * Shadows the {@code android.app.Application} class.
 */
@SuppressWarnings({"UnusedDeclaration"})
@Implements(Application.class)
public class ShadowApplication extends ShadowContextWrapper {
    private static final Map<String, String> SYSTEM_SERVICE_MAP = new HashMap<String, String>();

    static {
        // note that these are different!
    	// They specify concrete classes within Robolectric for interfaces or abstract classes defined by Android
        SYSTEM_SERVICE_MAP.put(Context.WINDOW_SERVICE, "com.xtremelabs.robolectric.tester.android.view.TestWindowManager");
        SYSTEM_SERVICE_MAP.put(Context.CLIPBOARD_SERVICE, "com.xtremelabs.robolectric.tester.android.text.TestClipboardManager");
        SYSTEM_SERVICE_MAP.put(Context.SENSOR_SERVICE, "android.hardware.TestSensorManager");
        SYSTEM_SERVICE_MAP.put(Context.VIBRATOR_SERVICE, "android.os.TestVibrator");
        
        // the rest are as mapped in docs...
        SYSTEM_SERVICE_MAP.put(Context.LAYOUT_INFLATER_SERVICE, "android.view.LayoutInflater");
        SYSTEM_SERVICE_MAP.put(Context.ACTIVITY_SERVICE, "android.app.ActivityManager");
        SYSTEM_SERVICE_MAP.put(Context.POWER_SERVICE, "android.os.PowerManager");
        SYSTEM_SERVICE_MAP.put(Context.ALARM_SERVICE, "android.app.AlarmManager");
        SYSTEM_SERVICE_MAP.put(Context.NOTIFICATION_SERVICE, "android.app.NotificationManager");
        SYSTEM_SERVICE_MAP.put(Context.KEYGUARD_SERVICE, "android.app.KeyguardManager");
        SYSTEM_SERVICE_MAP.put(Context.LOCATION_SERVICE, "android.location.LocationManager");
        SYSTEM_SERVICE_MAP.put(Context.SEARCH_SERVICE, "android.app.SearchManager");
        SYSTEM_SERVICE_MAP.put(Context.STORAGE_SERVICE, "android.os.storage.StorageManager");
        SYSTEM_SERVICE_MAP.put(Context.CONNECTIVITY_SERVICE, "android.net.ConnectivityManager");
        SYSTEM_SERVICE_MAP.put(Context.WIFI_SERVICE, "android.net.wifi.WifiManager");
        SYSTEM_SERVICE_MAP.put(Context.AUDIO_SERVICE, "android.media.AudioManager");
        SYSTEM_SERVICE_MAP.put(Context.TELEPHONY_SERVICE, "android.telephony.TelephonyManager");
        SYSTEM_SERVICE_MAP.put(Context.INPUT_METHOD_SERVICE, "android.view.inputmethod.InputMethodManager");
        SYSTEM_SERVICE_MAP.put(Context.UI_MODE_SERVICE, "android.app.UiModeManager");
        SYSTEM_SERVICE_MAP.put(Context.DOWNLOAD_SERVICE, "android.app.DownloadManager");
    }

    @RealObject private Application realApplication;

    private ResourceLoader resourceLoader;
    private ContentResolver contentResolver;
    private Map<String, Object> systemServices = new HashMap<String, Object>();
    private List<Intent> startedActivities = new ArrayList<Intent>();
    private List<Intent> startedServices = new ArrayList<Intent>();
    private List<Intent> stoppedServies = new ArrayList<Intent>();
    private List<Intent> broadcastIntents = new ArrayList<Intent>();
    private List<ServiceConnection> unboundServiceConnections = new ArrayList<ServiceConnection>();
    private List<Wrapper> registeredReceivers = new ArrayList<Wrapper>();
    private Map<String, Intent> stickyIntents = new HashMap<String, Intent>();
    private FakeHttpLayer fakeHttpLayer = new FakeHttpLayer();
    private Looper mainLooper = ShadowLooper.myLooper();
    private Scheduler backgroundScheduler = new Scheduler();
    private Map<String, Map<String, Object>> sharedPreferenceMap = new HashMap<String, Map<String, Object>>();
    private ArrayList<Toast> shownToasts = new ArrayList<Toast>();
    private ShadowAlertDialog latestAlertDialog;
    private ShadowDialog latestDialog;
    private Object bluetoothAdapter = Robolectric.newInstanceOf("android.bluetooth.BluetoothAdapter");
    private Resources resources;

    // these are managed by the AppSingletonizier... kinda gross, sorry [xw]
    LayoutInflater layoutInflater;
    AppWidgetManager appWidgetManager;
    private ServiceConnection serviceConnection;
    private ComponentName componentNameForBindService;
    private IBinder serviceForBindService;
    private List<String> unbindableActions = new ArrayList<String>();

    /**
     * Associates a {@code ResourceLoader} with an {@code Application} instance
     *
     * @param application    application
     * @param resourceLoader resource loader
     * @return the application
     *         todo: make this non-static?
     */
    public static Application bind(Application application, ResourceLoader resourceLoader) {
        ShadowApplication shadowApplication = shadowOf(application);
        if (shadowApplication.resourceLoader != null) throw new RuntimeException("ResourceLoader already set!");
        shadowApplication.resourceLoader = resourceLoader;
        shadowApplication.resources = ShadowResources.bind(new Resources(null, null, null), resourceLoader);        
        return application;
    }

    public List<Toast> getShownToasts() {
        return shownToasts;
    }

    public Scheduler getBackgroundScheduler() {
        return backgroundScheduler;
    }

    @Override
    @Implementation
    public Context getApplicationContext() {
        return realApplication;
    }

    @Override
    @Implementation
    public Resources getResources() {
        if (resources == null ) {
        	resources = ShadowResources.bind(new Resources(null, null, null), resourceLoader);
        }
        return resources;
    }

    @Implementation
    @Override
    public ContentResolver getContentResolver() {
        if (contentResolver == null) {
            contentResolver = new ContentResolver(realApplication) {
            };
        }
        return contentResolver;
    }

    @Implementation
    @Override
    public Object getSystemService(String name) {
        if (name.equals(Context.LAYOUT_INFLATER_SERVICE)) {
            return LayoutInflater.from(realApplication);
        } else {
            Object service = systemServices.get(name);
            if (service == null) {
                String serviceClassName = SYSTEM_SERVICE_MAP.get(name);
                if (serviceClassName != null) {
                    try {
                        service = newInstanceOf(Class.forName(serviceClassName));
                    } catch (ClassNotFoundException e) {
                        throw new RuntimeException(e);
                    }
                    systemServices.put(name, service);
                }
            }
            return service;
        }
    }

    @Implementation
    @Override
    public void startActivity(Intent intent) {
        startedActivities.add(intent);
    }

    @Implementation
    @Override
    public ComponentName startService(Intent intent) {
        startedServices.add(intent);
        return new ComponentName("some.service.package", "SomeServiceName-FIXME");
    }

    @Implementation
    @Override
    public boolean stopService(Intent name) {
        stoppedServies.add(name);

        return startedServices.contains(name);
    }

    public void setComponentNameAndServiceForBindService(ComponentName name, IBinder service) {
        this.componentNameForBindService = name;
        this.serviceForBindService = service;
    }

    @Implementation
    public boolean bindService(Intent intent, final ServiceConnection serviceConnection, int i) {
        if (unbindableActions.contains(intent.getAction())) {
            return false;
        }
        startedServices.add(intent);
        shadowOf(Looper.getMainLooper()).post(new Runnable() {
            @Override
            public void run() {
                serviceConnection.onServiceConnected(componentNameForBindService, serviceForBindService);
            }
        }, 0);
        return true;
    }

    @Implementation
    public void unbindService(final ServiceConnection serviceConnection) {
        unboundServiceConnections.add(serviceConnection);
        shadowOf(Looper.getMainLooper()).post(new Runnable() {
            @Override
            public void run() {
                serviceConnection.onServiceDisconnected(componentNameForBindService);
            }
        }, 0);
    }

    public List<ServiceConnection> getUnboundServiceConnections() {
        return unboundServiceConnections;
    }
    /**
     * Consumes the most recent {@code Intent} started by {@link #startActivity(android.content.Intent)} and returns it.
     *
     * @return the most recently started {@code Intent}
     */
    @Override
    public Intent getNextStartedActivity() {
        if (startedActivities.isEmpty()) {
            return null;
        } else {
            return startedActivities.remove(0);
        }
    }

    /**
     * Returns the most recent {@code Intent} started by {@link #startActivity(android.content.Intent)} without
     * consuming it.
     *
     * @return the most recently started {@code Intent}
     */
    @Override
    public Intent peekNextStartedActivity() {
        if (startedActivities.isEmpty()) {
            return null;
        } else {
            return startedActivities.get(0);
        }
    }

    /**
     * Consumes the most recent {@code Intent} started by {@link #startService(android.content.Intent)} and returns it.
     *
     * @return the most recently started {@code Intent}
     */
    @Override
    public Intent getNextStartedService() {
        if (startedServices.isEmpty()) {
            return null;
        } else {
            return startedServices.remove(0);
        }
    }

    /**
     * Returns the most recent {@code Intent} started by {@link #startService(android.content.Intent)} without
     * consuming it.
     *
     * @return the most recently started {@code Intent}
     */
    @Override
    public Intent peekNextStartedService() {
        if (startedServices.isEmpty()) {
            return null;
        } else {
            return startedServices.get(0);
        }
    }

    /**
     * Clears all {@code Intent} started by {@link #startService(android.content.Intent)}
     */
    @Override
    public void clearStartedServices() {
        startedServices.clear();
    }

    /**
     * Consumes the {@code Intent} requested to stop a service by {@link #stopService(android.content.Intent)}
     * from the bottom of the stack of stop requests.
     */
    @Override
    public Intent getNextStoppedService() {
        if (stoppedServies.isEmpty()) {
            return null;
        } else {
            return stoppedServies.remove(0);
        }
    }

    /**
     * Non-Android accessor (and a handy way to get a working {@code ResourceLoader}
     *
     * @return the {@code ResourceLoader} associated with this Application
     */
    public ResourceLoader getResourceLoader() {
        return resourceLoader;
    }

    /**
     * Broadcasts the {@code Intent} by iterating through the registered receivers, invoking their filters, and calling
     * {@code onRecieve(Application, Intent)} as appropriate. Does not enqueue the {@code Intent} for later inspection.
     *
     * @param intent the {@code Intent} to broadcast
     *               todo: enqueue the Intent for later inspection
     */
    @Override
    @Implementation
    public void sendBroadcast(Intent intent) {
        broadcastIntents.add(intent);
		
        List<Wrapper> copy = new ArrayList<Wrapper>();
        copy.addAll(registeredReceivers);
        for (Wrapper wrapper : copy) {
            if (wrapper.intentFilter.matchAction(intent.getAction())) {
                wrapper.broadcastReceiver.onReceive(realApplication, intent);
            }
        }
    }
	
    public List<Intent> getBroadcastIntents() {
        return broadcastIntents;
    }

    @Implementation
    public void sendStickyBroadcast(Intent intent) {
        stickyIntents.put(intent.getAction(), intent);
        sendBroadcast(intent);
    }

    /**
     * Always returns {@code null}
     *
     * @return {@code null}
     */
    @Override
    @Implementation
    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
        return registerReceiverWithContext(receiver, filter, realApplication);
    }

    Intent registerReceiverWithContext(BroadcastReceiver receiver, IntentFilter filter, Context context) {
        if (receiver != null) {
            registeredReceivers.add(new Wrapper(receiver, filter, context));
        }
        return getStickyIntent(filter);
    }

    private Intent getStickyIntent(IntentFilter filter) {
        for (Intent stickyIntent : stickyIntents.values()) {
            String action = null;
            for (int i = 0; i < filter.countActions(); i++) {
                action = filter.getAction(i);
                if (stickyIntent.getAction().equals(action)) {
                    return stickyIntent;
                }
            }
        }

        return null;
    }

    @Override
    @Implementation
    public void unregisterReceiver(BroadcastReceiver broadcastReceiver) {
        boolean found = false;
        Iterator<Wrapper> iterator = registeredReceivers.iterator();
        while (iterator.hasNext()) {
            Wrapper wrapper = iterator.next();
            if (wrapper.broadcastReceiver == broadcastReceiver) {
                iterator.remove();
                found = true;
            }
        }
        if (!found) {
            throw new IllegalArgumentException("Receiver not registered: " + broadcastReceiver);
        }
    }

    /**
     * Iterates through all of the registered receivers on this {@code Application} and if any of them match the given
     * {@code Context} object throws a {@code RuntimeException}
     *
     * @param context the {@code Context} to check for on each of the remaining registered receivers
     * @param type    the type to report for the context if an exception is thrown
     * @throws RuntimeException if there are any recievers registered with the given {@code Context}
     */
    public void assertNoBroadcastListenersRegistered(Context context, String type) {
        for (Wrapper registeredReceiver : registeredReceivers) {
            if (registeredReceiver.context == context) {
                RuntimeException e = new IllegalStateException(type + " " + context + " leaked has leaked IntentReceiver "
                        + registeredReceiver.broadcastReceiver + " that was originally registered here. " +
                        "Are you missing a call to unregisterReceiver()?");
                e.setStackTrace(registeredReceiver.exception.getStackTrace());
                throw e;
            }
        }
    }

    public void assertNoBroadcastListenersOfActionRegistered(Context context, String action) {
        for (Wrapper registeredReceiver : registeredReceivers) {
            if (registeredReceiver.context == context) {
                Iterator<String> actions = registeredReceiver.intentFilter.actionsIterator();
                while (actions.hasNext()) {
                    if (actions.next().equals(action)) {
                        RuntimeException e = new IllegalStateException("Unexpected BroadcastReceiver on " + context +
                                " with action " + action + " "
                                + registeredReceiver.broadcastReceiver + " that was originally registered here:");
                        e.setStackTrace(registeredReceiver.exception.getStackTrace());
                        throw e;
                    }
                }
            }
        }
    }

    public boolean hasReceiverForIntent(Intent intent) {
        for (Wrapper wrapper : registeredReceivers) {
            if (wrapper.intentFilter.matchAction(intent.getAction())) {
                return true;
            }
        }
        return false;
    }

    public List<BroadcastReceiver> getReceiversForIntent(Intent intent) {
        ArrayList<BroadcastReceiver> broadcastReceivers = new ArrayList<BroadcastReceiver>();
        for (Wrapper wrapper : registeredReceivers) {
            if (wrapper.intentFilter.matchAction(intent.getAction())) {
                broadcastReceivers.add(wrapper.getBroadcastReceiver());
            }
        }
        return broadcastReceivers;
    }

    /**
     * Non-Android accessor.
     *
     * @return list of {@link Wrapper}s for registered receivers
     */
    public List<Wrapper> getRegisteredReceivers() {
        return registeredReceivers;
    }

    /**
     * Non-Android accessor.
     *
     * @return the layout inflater used by this {@code Application}
     */
    public LayoutInflater getLayoutInflater() {
        return layoutInflater;
    }

    /**
     * Non-Android accessor.
     *
     * @return the app widget manager used by this {@code Application}
     */
    public AppWidgetManager getAppWidgetManager() {
        return appWidgetManager;
    }

    public FakeHttpLayer getFakeHttpLayer() {
        return fakeHttpLayer;
    }

    @Override
    @Implementation
    public Looper getMainLooper() {
        return mainLooper;
    }

    public Map<String, Map<String, Object>> getSharedPreferenceMap() {
        return sharedPreferenceMap;
    }

    public ShadowAlertDialog getLatestAlertDialog() {
        return latestAlertDialog;
    }

    public void setLatestAlertDialog(ShadowAlertDialog latestAlertDialog) {
        this.latestAlertDialog = latestAlertDialog;
    }

    public ShadowDialog getLatestDialog() {
        return latestDialog;
    }

    public void setLatestDialog(ShadowDialog latestDialog) {
        this.latestDialog = latestDialog;
    }

    public Object getBluetoothAdapter() {
        return bluetoothAdapter;
    }

    public void declareActionUnbindable(String action) {
        unbindableActions.add(action);
    }

    public void setSystemService(String key, Object service) {
        systemServices.put(key, service);
    }

    public class Wrapper {
        public BroadcastReceiver broadcastReceiver;
        public IntentFilter intentFilter;
        public Context context;
        public Throwable exception;

        public Wrapper(BroadcastReceiver broadcastReceiver, IntentFilter intentFilter, Context context) {
            this.broadcastReceiver = broadcastReceiver;
            this.intentFilter = intentFilter;
            this.context = context;
            exception = new Throwable();
        }

        public BroadcastReceiver getBroadcastReceiver() {
            return broadcastReceiver;
        }

        public IntentFilter getIntentFilter() {
            return intentFilter;
        }

        public Context getContext() {
            return context;
        }
    }
}
