// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.chromium.webapk.shell_apk;

import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;

import org.chromium.webapk.lib.common.WebApkConstants;
import org.chromium.webapk.lib.common.WebApkMetaDataKeys;

import java.io.File;
import java.util.List;

/**
 * WebAPK's main Activity.
 */
public class MainActivity extends Activity {
    private static final String LAST_RESORT_HOST_BROWSER = "com.android.chrome";
    private static final String LAST_RESORT_HOST_BROWSER_APPLICATION_NAME = "Google Chrome";
    private static final String TAG = "cr_MainActivity";

    /**
     * Name of class which launches browser in WebAPK mode.
     */
    private static final String HOST_BROWSER_LAUNCHER_CLASS_NAME =
            "org.chromium.webapk.lib.runtime_library.HostBrowserLauncher";

    // Action for launching {@link WebappLauncherActivity}.
    // TODO(hanxi): crbug.com/737556. Replaces this string with the new WebAPK launch action after
    // it is propagated to all the Chrome's channels.
    public static final String ACTION_START_WEBAPK =
            "com.google.android.apps.chrome.webapps.WebappManager.ACTION_START_WEBAPP";

    // Must stay in sync with
    // {@link org.chromium.chrome.browser.ShortcutHelper#REUSE_URL_MATCHING_TAB_ELSE_NEW_TAB}.
    private static final String REUSE_URL_MATCHING_TAB_ELSE_NEW_TAB =
            "REUSE_URL_MATCHING_TAB_ELSE_NEW_TAB";

    /**
     * Key for passing app icon id.
     */
    private static final String KEY_APP_ICON_ID = "app_icon_id";

    /**
     * The URL to launch the WebAPK. Used in the case of deep-links (intents from other apps) that
     * fall into the WebAPK scope.
     */
    private String mOverrideUrl;

    /** The "start_url" baked in the AndroidManifest.xml. */
    private String mStartUrl;

    /**
     * Creates install Intent.
     * @param packageName Package to install.
     * @return The intent.
     */
    private static Intent createInstallIntent(String packageName) {
        String marketUrl = "market://details?id=" + packageName;
        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(marketUrl));
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        return intent;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Bundle metadata = WebApkUtils.readMetaData(this);
        if (metadata == null) {
            finish();
            return;
        }

        mOverrideUrl = getOverrideUrl();
        mStartUrl = (mOverrideUrl != null) ? mOverrideUrl
                                           : metadata.getString(WebApkMetaDataKeys.START_URL);
        if (mStartUrl == null) {
            finish();
            return;
        }

        // The WebAPK may have been launched as a result of an intent filter for a different
        // scheme or top level domain. Rewrite the scheme and host name to the scope's
        // scheme and host name.
        String scopeUrl = metadata.getString(WebApkMetaDataKeys.SCOPE);
        if (!TextUtils.isEmpty(scopeUrl)) {
            Uri parsedStartUrl = Uri.parse(mStartUrl);
            Uri parsedScope = Uri.parse(scopeUrl);
            mStartUrl = parsedStartUrl.buildUpon()
                                .scheme(parsedScope.getScheme())
                                .encodedAuthority(parsedScope.getEncodedAuthority())
                                .build()
                                .toString();
        }

        Log.v(TAG, "Url of the WebAPK: " + mStartUrl);
        String packageName = getPackageName();
        Log.v(TAG, "Package name of the WebAPK:" + packageName);

        String runtimeHostInPreferences = WebApkUtils.getHostBrowserFromSharedPreference(this);
        String runtimeHost = WebApkUtils.getHostBrowserPackageName(this);
        if (!TextUtils.isEmpty(runtimeHostInPreferences)
                && !runtimeHostInPreferences.equals(runtimeHost)) {
            deleteSharedPref(this);
            deleteInternalStorage();
        }

        if (!TextUtils.isEmpty(runtimeHost)) {
            launchInHostBrowser(runtimeHost);
            finish();
            return;
        }

        List<ResolveInfo> infos = WebApkUtils.getInstalledBrowserResolveInfos(getPackageManager());
        if (hasBrowserSupportingWebApks(infos)) {
            showChooseHostBrowserDialog(infos);
        } else {
            showInstallHostBrowserDialog(metadata);
        }
    }

    /** Deletes the SharedPreferences. */
    private void deleteSharedPref(Context context) {
        SharedPreferences sharedPref =
                context.getSharedPreferences(WebApkConstants.PREF_PACKAGE, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPref.edit();
        editor.clear();
        editor.apply();
    }

    /** Deletes the internal storage. */
    private void deleteInternalStorage() {
        deletePath(getCacheDir());
        deletePath(getFilesDir());
        deletePath(getDir(HostBrowserClassLoader.DEX_DIR_NAME, Context.MODE_PRIVATE));
    }

    private void deletePath(File file) {
        if (file == null) return;

        if (file.isDirectory()) {
            File[] children = file.listFiles();
            if (children != null) {
                for (File child : children) {
                    deletePath(child);
                }
            }
        }

        if (!file.delete()) {
            Log.e(TAG, "Failed to delete : " + file.getAbsolutePath());
        }
    }

    private void launchInHostBrowser(String runtimeHost) {
        boolean forceNavigation = false;
        int source = getIntent().getIntExtra(WebApkConstants.EXTRA_SOURCE, 0);
        if (mOverrideUrl != null) {
            if (source == WebApkConstants.SHORTCUT_SOURCE_UNKNOWN) {
                source = WebApkConstants.SHORTCUT_SOURCE_EXTERNAL_INTENT;
            }
            forceNavigation =
                    getIntent().getBooleanExtra(WebApkConstants.EXTRA_FORCE_NAVIGATION, true);
        }

        // The override URL is non null when the WebAPK is launched from a deep link. The WebAPK
        // should navigate to the URL in the deep link even if the WebAPK is already open.
        Intent intent = new Intent();
        intent.setAction(ACTION_START_WEBAPK);
        intent.setPackage(runtimeHost);
        intent.putExtra(WebApkConstants.EXTRA_URL, mStartUrl)
                .putExtra(WebApkConstants.EXTRA_SOURCE, source)
                .putExtra(WebApkConstants.EXTRA_WEBAPK_PACKAGE_NAME, getPackageName())
                .putExtra(WebApkConstants.EXTRA_FORCE_NAVIGATION, forceNavigation);

        try {
            startActivity(intent);
        } catch (ActivityNotFoundException e) {
            Log.w(TAG, "Unable to launch browser in WebAPK mode.");
            e.printStackTrace();
        }
    }

    /**
     * Launches the Play Store with the host browser's page.
     */
    private void installBrowser(String hostBrowserPackageName) {
        try {
            startActivity(createInstallIntent(hostBrowserPackageName));
        } catch (ActivityNotFoundException e) {
        }
    }

    /** Retrieves URL from the intent's data. Returns null if a URL could not be retrieved. */
    private String getOverrideUrl() {
        String overrideUrl = getIntent().getDataString();
        if (overrideUrl != null
                && (overrideUrl.startsWith("https:") || overrideUrl.startsWith("http:"))) {
            return overrideUrl;
        }
        return null;
    }

    /** Returns whether there is any installed browser supporting WebAPKs. */
    private static boolean hasBrowserSupportingWebApks(List<ResolveInfo> resolveInfos) {
        List<String> browsersSupportingWebApk = WebApkUtils.getBrowsersSupportingWebApk();
        for (ResolveInfo info : resolveInfos) {
            if (browsersSupportingWebApk.contains(info.activityInfo.packageName)) {
                return true;
            }
        }
        return false;
    }

    /** Shows a dialog to choose the host browser. */
    private void showChooseHostBrowserDialog(List<ResolveInfo> infos) {
        ChooseHostBrowserDialog.DialogListener listener =
                new ChooseHostBrowserDialog.DialogListener() {
                    @Override
                    public void onHostBrowserSelected(String selectedHostBrowser) {
                        launchInHostBrowser(selectedHostBrowser);
                        WebApkUtils.writeHostBrowserToSharedPref(
                                MainActivity.this, selectedHostBrowser);
                        finish();
                    }
                    @Override
                    public void onQuit() {
                        finish();
                    }
                };
        ChooseHostBrowserDialog.show(this, listener, infos, getString(R.string.name));
    }

    /** Shows a dialog to install the host browser. */
    private void showInstallHostBrowserDialog(Bundle metadata) {
        String lastResortHostBrowserPackageName =
                metadata.getString(WebApkMetaDataKeys.RUNTIME_HOST);
        String lastResortHostBrowserApplicationName =
                metadata.getString(WebApkMetaDataKeys.RUNTIME_HOST_APPLICATION_NAME);

        if (TextUtils.isEmpty(lastResortHostBrowserPackageName)) {
            // WebAPKs without runtime host specified in the AndroidManifest.xml always install
            // Google Chrome as the default host browser.
            lastResortHostBrowserPackageName = LAST_RESORT_HOST_BROWSER;
            lastResortHostBrowserApplicationName = LAST_RESORT_HOST_BROWSER_APPLICATION_NAME;
        }

        InstallHostBrowserDialog.DialogListener listener =
                new InstallHostBrowserDialog.DialogListener() {
                    @Override
                    public void onConfirmInstall(String packageName) {
                        installBrowser(packageName);
                        WebApkUtils.writeHostBrowserToSharedPref(MainActivity.this, packageName);
                        finish();
                    }
                    @Override
                    public void onConfirmQuit() {
                        finish();
                    }
                };

        InstallHostBrowserDialog.show(this, listener, getString(R.string.name),
                lastResortHostBrowserPackageName, lastResortHostBrowserApplicationName,
                R.drawable.last_resort_runtime_host_logo);
    }
}
