package o2mc.io.dimmldependency.Datastreams;

import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;

import org.json.JSONException;
import org.json.JSONObject;

import java.net.SocketException;
import java.util.ArrayList;

import o2mc.io.dimmldependency.Tracker;
import o2mc.io.dimmldependency.viewMapper.DatastreamsViewmapper;

/**
 * Created by nickyromeijn on 05/02/16.
 * Adversitement Property
 * Extension on Datastreams & Dimml
 *
 * Root object of the library
 * Initialised by only the application context
 * Has activity state listeners and triggers data tracking
 */

public class Datastream implements Application.ActivityLifecycleCallbacks {

    private Application context;
    private String deviceId = null;
    private Double latitude;
    private Double longitude;
    private LocationManager mLocationManager = null;
    DatastreamsHandler datastreamsHandler;
    private ArrayList<String> hasBeenMapped = new ArrayList<>();
    private static String ApplicationKey = null;
    public final Tracker tracker;

    public Datastream(Application ctx, String appKey) {
        context = ctx;
        context.registerActivityLifecycleCallbacks(this);
        datastreamsHandler = new DatastreamsHandler(ctx);
        ApplicationKey = appKey;
        tracker = new Tracker(this);
    }

    public Tracker getTracker(){
        return tracker;
    }

    @Override
    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
        if (deviceId == null)
            deviceId = Settings.Secure.getString(activity.getContentResolver(), Settings.Secure.ANDROID_ID);
        if (mLocationManager == null) {
//            && (hasPermission("ACCESS_FINE_LOCATION", activity) || hasPermission("ACCESS_COARSE_LOCATION", activity) )
            mLocationManager = (LocationManager) activity.getSystemService(Context.LOCATION_SERVICE);
            mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 0f, new DatastreamsLocation(this));
        }
    }

    @Override
    public void onActivityStarted(Activity activity) {
        //Add listener here
        datastreamsHandler.update(activity, null, getGeneralInfo());
    }

    @Override
    public void onActivityResumed(Activity activity) {
        if (!hasBeenMapped.contains(activity.getClass().getSimpleName()) && getSettings().mapViews()) {
            new DatastreamsViewmapper(activity);
            hasBeenMapped.add(activity.getClass().getSimpleName());
        }

    }

    @Override
    public void onActivityPaused(Activity activity) {
    }

    @Override
    public void onActivityStopped(Activity activity) {
        datastreamsHandler.update(activity, "exit", getGeneralInfo());
    }

    @Override
    public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

    }

    @Override
    public void onActivityDestroyed(Activity activity) {

    }

    /**
     * Returns a JSONObject with general device info
     * Unique deviceId
     * Phone type
     * connection info
     * operating system
     * ip address
     * location (if enabled)
     * @return
     */
    public JSONObject getGeneralInfo() {
        JSONObject root = new JSONObject();

        try {
            root.put("AppID", context.getPackageName());
            root.put("batch", datastreamsHandler.getDispatcher().getBatchCounter());

            if (getSettings().trackNetworkstate()) {
                root.put("ip", Connectivity.ip().getHostAddress().replace("\\",""));
                root.put("connection", Connectivity.getConnectivityType(context));
            }

            root.put("operatingSystem", Build.VERSION.RELEASE);
            root.put("device", DeviceName.getDeviceName());

            if (getSettings().trackLocation()) {
                root.put("location", new JSONObject().put("latitude", latitude).put("longtitude", longitude));
            }
            if (getSettings().trackUnique()) {
                deviceId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
                root.put("deviceID", deviceId);
            }

        } catch (JSONException e) {
            e.printStackTrace();
        } catch (SocketException e) {
            e.printStackTrace();
        }


        return root;
    }

    public boolean hasPermission(String permission, Context context) {
        try {
            PackageInfo info = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_PERMISSIONS);
            if (info.requestedPermissions != null) {
                for (String p : info.requestedPermissions) {
                    if (p.equals(permission)) {
                        return true;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    public DatastreamsHandler getDatastreamsHandler() {
        return datastreamsHandler;
    }

    public void setLatitude(Double latitude) {
        this.latitude = latitude;
    }

    public void setLongitude(Double longitude) {
        this.longitude = longitude;
    }

    public Double getLatitude() {
        return latitude;
    }

    public Double getLongitude() {
        return longitude;
    }

    public DatastreamsSettings getSettings() {
        return datastreamsHandler.getSettings();
    }

    public static String getApplicationKey() {
        return ApplicationKey;
    }

    public void setIdentity(String identity){
        getDatastreamsHandler().setIdentity(identity);
    }
    public void setAlias(String alias){
        getDatastreamsHandler().setAlias(alias);
    }
}