package com.mobify.astro;

import android.os.Bundle;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.support.annotation.NonNull;
import android.view.View;

import com.mobify.astro.messaging.AddressableObject;
import com.mobify.astro.messaging.EventMessage;
import com.mobify.astro.messaging.EventRegistrar;
import com.mobify.astro.messaging.MessageSender;
import com.mobify.astro.messaging.RpcMessageListener;

import com.mobify.astro.messaging.annotations.RpcMethod;

import org.json.JSONObject;

public abstract class AstroPlugin extends RpcMessageListener implements AddressableObject {
    private static final String TAG = AstroPlugin.class.getName();

    private String instanceName;

    protected AstroActivity activity;
    protected PluginResolver pluginResolver;
    protected Bundle savedPluginState;

    public AstroPlugin(@NonNull AstroActivity activity, @NonNull PluginResolver pluginResolver,
                       @NonNull EventRegistrar eventRegistrar, @NonNull MessageSender messageSender) {
        super(eventRegistrar, messageSender);
        this.activity = activity;
        this.pluginResolver = pluginResolver;

        savedPluginState = new Bundle();

        initialize();
    }

    public void onPause() {}

    public void destroy() {}

    /**
     * Override this method to perform logic after a plugin is created.
     */
    protected void initialize() {}

    /**
     * Override this method to return a view to other plugins.
     */
    public View getView() {
         throw new UnsupportedOperationException("getView() not supported on " + this.getClass());
    }

    /**
     * Return the name of this plugin instance
     * @return the name of the plugin instance
     */
    public String getInstanceName() {
        return instanceName;
    }

    /**
     * Returns the bundle with the plugin's saved state
     * @return a bundle containing any state the plugin has saved
     */
    public Bundle getSavedPluginState() {
        return savedPluginState;
    }

    /**
     * Triggers an event on the plugin's event channel.
     */
    public void triggerEvent(String eventName, JSONObject params) {
        EventMessage message = new EventMessage(eventName, params, this);
        messageSender.sendMessageToAddress(message, getEventsAddress());
    }

    /**
     * Determines whether or not the device is currently connected to the internet.
     */
    public boolean isOffline() {
        ConnectivityManager connectivityManager =
                (ConnectivityManager)this.activity.getSystemService(Context.CONNECTIVITY_SERVICE);

        NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();

        if (networkInfo != null && networkInfo.isConnectedOrConnecting()) {
            return false;
        }
        return true;
    }

    /**
     * Sets the name of this plugin
     * @param name The name of the plugin
     */
    @RpcMethod(methodName = "setInstanceName", parameterNames={"name"})
    public void setInstanceName(String name) {
        this.instanceName = name;
    }
}
