/*
 * Copyright (c) 2012-2016 Arne Schwabe
 * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt
 */

package de.blinkt.openvpn.core;
import android.app.Activity;
import android.app.Application;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;

/*
import org.acra.ACRA;
import org.acra.ReportingInteractionMode;
import org.acra.annotation.ReportsCrashes;
*/

import com.routeone.dc.vpn.DcUtils;
import com.routeone.dc.vpn.ForwardedDcIntentReceiver;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

import de.blinkt.openvpn.BuildConfig;
import de.blinkt.openvpn.R;
import de.blinkt.openvpn.core.PRNGFixes;

/*
@ReportsCrashes(
        formKey = "",
        formUri = "http://reports.blinkt.de/report-icsopenvpn",
        reportType = org.acra.sender.HttpSender.Type.JSON,
        httpMethod = org.acra.sender.HttpSender.Method.PUT,
        formUriBasicAuthLogin="report-icsopenvpn",
        formUriBasicAuthPassword="Tohd4neiF9Ai!!!!111eleven",
        mode = ReportingInteractionMode.TOAST,
        resToastText = R.string.crash_toast_text
)
*/
public class ICSOpenVPNApplication extends Application {

/*
 * This section is a derivative work from the original project.
 *
 * -----  Beginning of Section  -----
 *
 * Copyright (c) 2016 Route1 Inc.  All rights reserved.  <sales@route1.com>
 *
 * You may use, distribute and modify this code under the
 * terms of the GNU General Public License version 2
 * as published by the Free Software Foundation.

 * Contributor:  A. M. Jehad Sarkar  <amjehad.sarkar@route1.com>
 */
    private static final String TAG = ICSOpenVPNApplication.class.getSimpleName();

    static private ICSOpenVPNApplication singleton;
    static public ICSOpenVPNApplication getInstance() {
        return singleton;
    }

    static public boolean route1Configuration = true;
    static public String helpURL = "https://www.route1.com/support.html";

    public MyActivityLifecycleCallbacks myActivityLifecycleCallbacks = null;

    public boolean pinDialogDoneOnStartup = false;

/*
 * -----  End of Section  -----
 * Copyright (c) 2016 Route1 Inc.  All rights reserved.  <sales@route1.com>
 */

    @Override
    public void onCreate() {
        super.onCreate();
        PRNGFixes.apply();

        if (BuildConfig.DEBUG) {
            //ACRA.init(this);
        }

        VpnStatus.initLogCache(getApplicationContext().getCacheDir());

/*
 * This section is a derivative work from the original project.
 *
 * -----  Beginning of Section  -----
 *
 * Copyright (c) 2016 Route1 Inc.  All rights reserved.  <sales@route1.com>
 *
 * You may use, distribute and modify this code under the
 * terms of the GNU General Public License version 2
 * as published by the Free Software Foundation.

 * Contributor:  A. M. Jehad Sarkar  <amjehad.sarkar@route1.com>
 */
        singleton = this;
        registerActivityLifecycleCallbacks( myActivityLifecycleCallbacks = new MyActivityLifecycleCallbacks() );

/*
 * -----  End of Section  -----
 * Copyright (c) 2016 Route1 Inc.  All rights reserved.  <sales@route1.com>
 */
    }


    /*
     * This section is a derivative work from the original project.
     *
     * -----  Beginning of Section  -----
     *
     * Copyright (c) 2016 Route1 Inc.  All rights reserved.  <sales@route1.com>
     *
     * You may use, distribute and modify this code under the
     * terms of the GNU General Public License version 2
     * as published by the Free Software Foundation.

     * Contributor:  A. M. Jehad Sarkar  <amjehad.sarkar@route1.com>
     */
    public ForwardedDcIntentReceiver mDcReceiver;

    ///// foreground or background - start /////////////////////////////////////////////////////
    // Copied from: com.routeone.dc.containerapp.DerivIDApp
    // See: http://steveliles.github.io/is_my_android_app_currently_foreground_or_background.html
    public interface FGBGListener {
        public void onBecameForeground();
        public void onBecameBackground();
    }


    public /*static*/ final class MyActivityLifecycleCallbacks
            implements ActivityLifecycleCallbacks
    {

        @Override
        public void onActivityCreated(Activity activity, Bundle bundle) {
            //Log.d(TAG, "onActivityCreated:" + activity.getLocalClassName());
        }

        @Override
        public void onActivityDestroyed(Activity activity) {
            //Log.d(TAG, "onActivityDestroyed:" + activity.getLocalClassName());
        }

        ///// foreground or background - start
        private static final long APP_WENT_BACKGROUND_CHECK_DELAY = 500;
        private boolean foreground = false;
        private boolean paused = true;
        private Handler handler = new Handler();
        private Runnable check;

        private List<FGBGListener> listeners = new CopyOnWriteArrayList<FGBGListener>();
        public void addListener(FGBGListener listener) {listeners.add(listener);}
        public void removeListener(FGBGListener listener) {listeners.remove(listener);}

        // Do we actually need these two?
        public boolean isForeground() {return foreground;}
        public boolean isBackground() {return !foreground;}
        ///// foreground or background - end

        @Override
        public void onActivityResumed(Activity activity) {
            //Log.d(TAG, "onActivityResumed:" + activity.getLocalClassName());

            paused = false;
            boolean wasBackground = !foreground;
            foreground = true;

            if (check != null) {
                handler.removeCallbacks(check);
            }

            if (wasBackground){
                Log.d(TAG, "resumed activity " + activity.getClass().getSimpleName() + ", app went foreground");

                /////
                mDcReceiver = DcUtils.registerDCReceiver(
                        //?//activity.getApplicationContext(),
                        getApplicationContext(),
                        mDcReceiver);
                /////

                // If I need to support registering listeners, then uncomment:
                for (FGBGListener l : listeners) {
                    try {
                        l.onBecameForeground();
                    } catch (Exception exc) {
                        Log.e(TAG, "FGBGListener threw exception!", exc);
                    }
                }
            } else {
                Log.d(TAG, "resumed activity " + activity.getClass().getSimpleName() + ", app still foreground");
            }
        }

        @Override
        public void onActivityPaused(final Activity activity) {
            //Log.d(TAG, "onActivityPaused:" + activity.getLocalClassName());

            paused = true;

            if (check != null) {
                handler.removeCallbacks(check);
            }

            handler.postDelayed(check = new Runnable(){
                @Override
                public void run() {
                    if (foreground && paused) {
                        foreground = false;
                        Log.d(TAG, "paused activity " + activity.getClass().getSimpleName() + ", app went background");

                        /////
                        DcUtils.unregisterDCReceiver(
                                //?//activity.getApplicationContext(),
                                getApplicationContext(),
                                mDcReceiver);
                        /////

                        // If I need to support registering listeners, then uncomment:
                        for (FGBGListener l : listeners) {
                            try {
                                l.onBecameBackground();
                            } catch (Exception exc) {
                                Log.e(TAG, "FGBGListener threw exception!", exc);
                            }
                        }
                    } else {
                        Log.d(TAG, "paused activity " + activity.getClass().getSimpleName() + ", app still foreground");
                    }
                }
            }, APP_WENT_BACKGROUND_CHECK_DELAY);
        }

        @Override
        public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
            //Log.d(TAG, "onActivitySaveInstanceState:" + activity.getLocalClassName());
        }
        @Override
        public void onActivityStarted(Activity activity) {
            //Log.d(TAG, "onActivityStarted:" + activity.getLocalClassName());
        }
        @Override
        public void onActivityStopped(Activity activity) {
            //Log.d(TAG, "onActivityStopped:" + activity.getLocalClassName());
        }
    }

    ///// foreground or background - end ///////////////////////////////////////////////////////


/*
 * -----  End of Section  -----
 * Copyright (c) 2016 Route1 Inc.  All rights reserved.  <sales@route1.com>
 */
}
