// 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.chrome.browser.webapps;

import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.text.TextUtils;

import org.chromium.base.Log;
import org.chromium.base.VisibleForTesting;
import org.chromium.blink_public.platform.WebDisplayMode;
import org.chromium.chrome.browser.ShortcutHelper;
import org.chromium.chrome.browser.ShortcutSource;
import org.chromium.chrome.browser.util.IntentUtils;
import org.chromium.content_public.common.ScreenOrientationValues;

/**
 * Stores info about a web app.
 */
public class WebappInfo {
    private static final String TAG = "WebappInfo";

    /**
     * Parameter for {@link WebappInfo#create()} method which allows either a Bitmap or a PNG
     * encoded string to be passed as a parameter.
     */
    public static class Icon {
        private String mEncoded;
        private Bitmap mDecoded;

        public Icon(String encoded) {
            mEncoded = encoded;
        }

        public Icon(Bitmap decoded) {
            mDecoded = decoded;
        }

        public String encoded() {
            if (mEncoded == null) {
                mEncoded = ShortcutHelper.encodeBitmapAsString(mDecoded);
            }
            return mEncoded;
        }

        public Bitmap decoded() {
            if (mDecoded == null) {
                mDecoded = ShortcutHelper.decodeBitmapFromString(mEncoded);
            }
            return mDecoded;
        }
    }

    private boolean mIsInitialized;
    private String mId;
    private Icon mIcon;
    private Uri mUri;
    private Uri mScopeUri;
    private String mName;
    private String mShortName;
    private int mDisplayMode;
    private int mOrientation;
    private int mSource;
    private long mThemeColor;
    private long mBackgroundColor;
    private boolean mIsIconGenerated;

    public static WebappInfo createEmpty() {
        return new WebappInfo();
    }

    protected static String urlFromIntent(Intent intent) {
        return IntentUtils.safeGetStringExtra(intent, ShortcutHelper.EXTRA_URL);
    }

    protected static int sourceFromIntent(Intent intent) {
        int source = IntentUtils.safeGetIntExtra(
                intent, ShortcutHelper.EXTRA_SOURCE, ShortcutSource.UNKNOWN);
        if (source >= ShortcutSource.COUNT) {
            source = ShortcutSource.UNKNOWN;
        }
        return source;
    }

    private static String titleFromIntent(Intent intent) {
        // The reference to title has been kept for reasons of backward compatibility. For intents
        // and shortcuts which were created before we utilized the concept of name and shortName,
        // we set the name and shortName to be the title.
        String title = IntentUtils.safeGetStringExtra(intent, ShortcutHelper.EXTRA_TITLE);
        return title == null ? "" : title;
    }

    private static String nameFromIntent(Intent intent) {
        String name = IntentUtils.safeGetStringExtra(intent, ShortcutHelper.EXTRA_NAME);
        return name == null ? titleFromIntent(intent) : name;
    }

    private static String shortNameFromIntent(Intent intent) {
        String shortName = IntentUtils.safeGetStringExtra(intent, ShortcutHelper.EXTRA_SHORT_NAME);
        return shortName == null ? titleFromIntent(intent) : shortName;
    }

    /**
     * Construct a WebappInfo.
     * @param intent Intent containing info about the app.
     */
    public static WebappInfo create(Intent intent) {
        String id = IntentUtils.safeGetStringExtra(intent, ShortcutHelper.EXTRA_ID);
        String icon = IntentUtils.safeGetStringExtra(intent, ShortcutHelper.EXTRA_ICON);
        String url = urlFromIntent(intent);
        String scope = IntentUtils.safeGetStringExtra(intent, ShortcutHelper.EXTRA_SCOPE);
        int displayMode = IntentUtils.safeGetIntExtra(
                intent, ShortcutHelper.EXTRA_DISPLAY_MODE, WebDisplayMode.STANDALONE);
        int orientation = IntentUtils.safeGetIntExtra(
                intent, ShortcutHelper.EXTRA_ORIENTATION, ScreenOrientationValues.DEFAULT);
        int source = sourceFromIntent(intent);
        long themeColor = IntentUtils.safeGetLongExtra(intent,
                ShortcutHelper.EXTRA_THEME_COLOR,
                ShortcutHelper.MANIFEST_COLOR_INVALID_OR_MISSING);
        long backgroundColor = IntentUtils.safeGetLongExtra(intent,
                ShortcutHelper.EXTRA_BACKGROUND_COLOR,
                ShortcutHelper.MANIFEST_COLOR_INVALID_OR_MISSING);
        boolean isIconGenerated = IntentUtils.safeGetBooleanExtra(intent,
                ShortcutHelper.EXTRA_IS_ICON_GENERATED, false);

        String name = nameFromIntent(intent);
        String shortName = shortNameFromIntent(intent);

        return create(id, url, scope, new Icon(icon), name, shortName, displayMode,
                orientation, source, themeColor, backgroundColor, isIconGenerated);
    }

    /**
     * Construct a WebappInfo.
     * @param id              ID for the webapp.
     * @param url             URL for the webapp.
     * @param scope           Scope for the webapp.
     * @param icon            Icon to show for the webapp.
     * @param name            Name of the webapp.
     * @param shortName       The short name of the webapp.
     * @param displayMode     Display mode of the webapp.
     * @param orientation     Orientation of the webapp.
     * @param source          Source where the webapp was added from.
     * @param themeColor      The theme color of the webapp.
     * @param backgroundColor The background color of the webapp.
     * @param isIconGenerated Whether the |icon| was generated by Chromium.
     */
    public static WebappInfo create(String id, String url, String scope, Icon icon, String name,
            String shortName, int displayMode, int orientation, int source, long themeColor,
            long backgroundColor, boolean isIconGenerated) {
        if (id == null || url == null) {
            Log.e(TAG, "Incomplete data provided: " + id + ", " + url);
            return null;
        }

        return new WebappInfo(id, url, scope, icon, name, shortName, displayMode, orientation,
                source, themeColor, backgroundColor, isIconGenerated);
    }

    protected WebappInfo(String id, String url, String scope, Icon icon, String name,
            String shortName, int displayMode, int orientation, int source, long themeColor,
            long backgroundColor, boolean isIconGenerated) {
        Uri uri = Uri.parse(url);
        if (TextUtils.isEmpty(scope)) {
            scope = ShortcutHelper.getScopeFromUrl(url);
        }
        Uri scopeUri = Uri.parse(scope);

        mIcon = icon;
        mId = id;
        mName = name;
        mShortName = shortName;
        mUri = uri;
        mScopeUri = scopeUri;
        mDisplayMode = displayMode;
        mOrientation = orientation;
        mSource = source;
        mThemeColor = themeColor;
        mBackgroundColor = backgroundColor;
        mIsIconGenerated = isIconGenerated;
        mIsInitialized = mUri != null;
    }

    protected WebappInfo() {
    }

    public boolean isInitialized() {
        return mIsInitialized;
    }

    public String id() {
        return mId;
    }

    public Uri uri() {
        return mUri;
    }

    /**
     * Whether the webapp should be navigated to {@link uri()} if the webapp is already open when
     * Chrome receives a ACTION_START_WEBAPP intent.
     */
    public boolean shouldForceNavigation() {
        return false;
    }

    public Uri scopeUri() {
        return mScopeUri;
    }

    public String name() {
        return mName;
    }

    public String shortName() {
        return mShortName;
    }

    public int displayMode() {
        return mDisplayMode;
    }

    public String webApkPackageName() {
        return null;
    }

    public int orientation() {
        return mOrientation;
    }

    public int source() {
        return mSource;
    }

    /**
     * Theme color is actually a 32 bit unsigned integer which encodes a color
     * in ARGB format. mThemeColor is a long because we also need to encode the
     * error state of ShortcutHelper.MANIFEST_COLOR_INVALID_OR_MISSING.
     */
    public long themeColor() {
        return mThemeColor;
    }

    /**
     * Returns whether the theme color specified in the Intent is valid.
     * A theme color isn't valid if its value is ShortcutHelper.MANIFEST_COLOR_INVALID_OR_MISSING;
     */
    public boolean hasValidThemeColor() {
        return mThemeColor != ShortcutHelper.MANIFEST_COLOR_INVALID_OR_MISSING;
    }

    /**
     * Background color is actually a 32 bit unsigned integer which encodes a color
     * in ARGB format. mBackgroundColor is a long because we also need to encode the
     * error state of ShortcutHelper.MANIFEST_COLOR_INVALID_OR_MISSING.
     */
    public long backgroundColor() {
        return mBackgroundColor;
    }

    /**
     * Returns whether the background color specified in the Intent is valid.
     * A background color isn't valid if its value is
     * ShortcutHelper.MANIFEST_COLOR_INVALID_OR_MISSING.
     */
    public boolean hasValidBackgroundColor() {
        return mBackgroundColor != ShortcutHelper.MANIFEST_COLOR_INVALID_OR_MISSING;
    }

    /**
     * Returns the background color specified by {@link #backgroundColor()} if
     * the value is valid. Returns the specified fallback color otherwise.
     */
    public int backgroundColor(int fallback) {
        return hasValidBackgroundColor() ? (int) mBackgroundColor : fallback;
    }

    // This is needed for clients that want to send the icon through an intent.
    public String encodedIcon() {
        return (mIcon == null) ? null : mIcon.encoded();
    }

    /**
     * Returns the icon in Bitmap form.  Caches the result for future retrievals.
     */
    public Bitmap icon() {
        return (mIcon == null) ? null : mIcon.decoded();
    }

    /**
     * Returns whether the icon was generated by Chromium.
     */
    public boolean isIconGenerated() {
        return mIsIconGenerated;
    }

    /**
     * Sets extras on an Intent that will launch a WebappActivity.
     * @param intent Intent that will be used to launch a WebappActivity.
     */
    public void setWebappIntentExtras(Intent intent) {
        intent.putExtra(ShortcutHelper.EXTRA_ID, id());
        intent.putExtra(ShortcutHelper.EXTRA_URL, uri().toString());
        intent.putExtra(ShortcutHelper.EXTRA_SCOPE, scopeUri().toString());
        intent.putExtra(ShortcutHelper.EXTRA_ICON, encodedIcon());
        intent.putExtra(ShortcutHelper.EXTRA_VERSION, ShortcutHelper.WEBAPP_SHORTCUT_VERSION);
        intent.putExtra(ShortcutHelper.EXTRA_NAME, name());
        intent.putExtra(ShortcutHelper.EXTRA_SHORT_NAME, shortName());
        intent.putExtra(ShortcutHelper.EXTRA_DISPLAY_MODE, displayMode());
        intent.putExtra(ShortcutHelper.EXTRA_ORIENTATION, orientation());
        intent.putExtra(ShortcutHelper.EXTRA_SOURCE, source());
        intent.putExtra(ShortcutHelper.EXTRA_THEME_COLOR, themeColor());
        intent.putExtra(ShortcutHelper.EXTRA_BACKGROUND_COLOR, backgroundColor());
        intent.putExtra(ShortcutHelper.EXTRA_IS_ICON_GENERATED, isIconGenerated());
    }

    /**
     * Returns true if the WebappInfo was created for an Intent fired from a launcher shortcut (as
     * opposed to an intent from a push notification or other internal source).
     */
    public boolean isLaunchedFromHomescreen() {
        int source = source();
        return source != ShortcutSource.NOTIFICATION && source != ShortcutSource.EXTERNAL_INTENT;
    }

    @VisibleForTesting
    void setScopeForTest(String scope) {
        mScopeUri = Uri.parse(scope);
    }
}
