/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.textclassifier.common.intent;

import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.text.TextUtils;
import androidx.annotation.DrawableRes;
import androidx.core.app.RemoteActionCompat;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.drawable.IconCompat;
import com.android.textclassifier.common.base.TcLog;
import com.google.common.base.Objects;
import com.google.common.base.Preconditions;
import javax.annotation.Nullable;

/** Helper class to store the information from which RemoteActions are built. */
public final class LabeledIntent {
  private static final String TAG = "LabeledIntent";
  public static final int DEFAULT_REQUEST_CODE = 0;
  private static final TitleChooser DEFAULT_TITLE_CHOOSER =
      (labeledIntent, resolveInfo) -> {
        if (!TextUtils.isEmpty(labeledIntent.titleWithEntity)) {
          return labeledIntent.titleWithEntity;
        }
        return labeledIntent.titleWithoutEntity;
      };

  @Nullable public final String titleWithoutEntity;
  @Nullable public final String titleWithEntity;
  public final String description;
  @Nullable public final String descriptionWithAppName;
  // Do not update this intent.
  public final Intent intent;
  public final int requestCode;

  /**
   * Initializes a LabeledIntent.
   *
   * <p>NOTE: {@code requestCode} is required to not be {@link #DEFAULT_REQUEST_CODE} if
   * distinguishing info (e.g. the classified text) is represented in intent extras only. In such
   * circumstances, the request code should represent the distinguishing info (e.g. by generating a
   * hashcode) so that the generated PendingIntent is (somewhat) unique. To be correct, the
   * PendingIntent should be definitely unique but we try a best effort approach that avoids
   * spamming the system with PendingIntents.
   */
  // TODO: Fix the issue mentioned above so the behaviour is correct.
  public LabeledIntent(
      @Nullable String titleWithoutEntity,
      @Nullable String titleWithEntity,
      String description,
      @Nullable String descriptionWithAppName,
      Intent intent,
      int requestCode) {
    if (TextUtils.isEmpty(titleWithEntity) && TextUtils.isEmpty(titleWithoutEntity)) {
      throw new IllegalArgumentException(
          "titleWithEntity and titleWithoutEntity should not be both null");
    }
    this.titleWithoutEntity = titleWithoutEntity;
    this.titleWithEntity = titleWithEntity;
    this.description = Preconditions.checkNotNull(description);
    this.descriptionWithAppName = descriptionWithAppName;
    this.intent = Preconditions.checkNotNull(intent);
    this.requestCode = requestCode;
  }

  /**
   * Return the resolved result.
   *
   * @param context the context to resolve the result's intent and action
   * @param titleChooser for choosing an action title
   */
  @Nullable
  public Result resolve(Context context, @Nullable TitleChooser titleChooser) {
    final PackageManager pm = context.getPackageManager();
    final ResolveInfo resolveInfo = pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);

    if (resolveInfo == null || resolveInfo.activityInfo == null) {
      // Failed to resolve the intent. It could be because there are no apps to handle
      // the intent. It could be also because the calling app has no visibility to the target app
      // due to the app visibility feature introduced on R. For privacy reason, we don't want to
      // force users of our library to ask for the visibility to the http/https view intent.
      // Getting visibility to this intent effectively means getting visibility of ~70% of apps.
      // This defeats the purpose of the app visibility feature. Practically speaking, all devices
      // are very likely to have a browser installed. Thus, if it is a web intent, we assume we
      // failed to resolve the intent just because of the app visibility feature. In which case, we
      // return an implicit intent without an icon.
      if (isWebIntent()) {
        IconCompat icon = IconCompat.createWithResource(context, android.R.drawable.ic_menu_more);
        RemoteActionCompat action =
            createRemoteAction(
                context, intent, icon, /* shouldShowIcon= */ false, resolveInfo, titleChooser);
        // Create a clone so that the client does not modify the original intent.
        return new Result(new Intent(intent), action);
      } else {
        TcLog.w(TAG, "resolveInfo or activityInfo is null");
        return null;
      }
    }
    if (!hasPermission(context, resolveInfo.activityInfo)) {
      TcLog.d(TAG, "No permission to access: " + resolveInfo.activityInfo);
      return null;
    }

    final String packageName = resolveInfo.activityInfo.packageName;
    final String className = resolveInfo.activityInfo.name;
    if (packageName == null || className == null) {
      TcLog.w(TAG, "packageName or className is null");
      return null;
    }
    Intent resolvedIntent = new Intent(intent);
    boolean shouldShowIcon = false;
    IconCompat icon = null;
    if (!"android".equals(packageName)) {
      // We only set the component name when the package name is not resolved to "android"
      // to workaround a bug that explicit intent with component name == ResolverActivity
      // can't be launched on keyguard.
      resolvedIntent.setComponent(new ComponentName(packageName, className));
      if (resolveInfo.activityInfo.getIconResource() != 0) {
        icon =
            createIconFromPackage(context, packageName, resolveInfo.activityInfo.getIconResource());
        shouldShowIcon = true;
      }
    }
    if (icon == null) {
      // RemoteAction requires that there be an icon.
      icon = IconCompat.createWithResource(context, android.R.drawable.ic_menu_more);
    }
    RemoteActionCompat action =
        createRemoteAction(
            context, resolvedIntent, icon, shouldShowIcon, resolveInfo, titleChooser);
    return new Result(resolvedIntent, action);
  }

  private RemoteActionCompat createRemoteAction(
      Context context,
      Intent resolvedIntent,
      IconCompat icon,
      boolean shouldShowIcon,
      @Nullable ResolveInfo resolveInfo,
      @Nullable TitleChooser titleChooser) {
    final PendingIntent pendingIntent = createPendingIntent(context, resolvedIntent, requestCode);
    titleChooser = titleChooser == null ? DEFAULT_TITLE_CHOOSER : titleChooser;
    CharSequence title = titleChooser.chooseTitle(this, resolveInfo);
    if (TextUtils.isEmpty(title)) {
      TcLog.w(TAG, "Custom titleChooser return null, fallback to the default titleChooser");
      title = DEFAULT_TITLE_CHOOSER.chooseTitle(this, resolveInfo);
    }
    final RemoteActionCompat action =
        new RemoteActionCompat(
            icon,
            title,
            resolveDescription(resolveInfo, context.getPackageManager()),
            pendingIntent);
    action.setShouldShowIcon(shouldShowIcon);
    return action;
  }

  private boolean isWebIntent() {
    if (!Intent.ACTION_VIEW.equals(intent.getAction())) {
      return false;
    }
    final String scheme = intent.getScheme();
    return Objects.equal(scheme, "http") || Objects.equal(scheme, "https");
  }

  private String resolveDescription(
      @Nullable ResolveInfo resolveInfo, PackageManager packageManager) {
    if (!TextUtils.isEmpty(descriptionWithAppName)) {
      // Example string format of descriptionWithAppName: "Use %1$s to open map".
      String applicationName = getApplicationName(resolveInfo, packageManager);
      if (!TextUtils.isEmpty(applicationName)) {
        return String.format(descriptionWithAppName, applicationName);
      }
    }
    return description;
  }

  @Nullable
  private static IconCompat createIconFromPackage(
      Context context, String packageName, @DrawableRes int iconRes) {
    try {
      Context packageContext = context.createPackageContext(packageName, 0);
      return IconCompat.createWithResource(packageContext, iconRes);
    } catch (PackageManager.NameNotFoundException e) {
      TcLog.e(TAG, "createIconFromPackage: failed to create package context", e);
    }
    return null;
  }

  private static PendingIntent createPendingIntent(
      final Context context, final Intent intent, int requestCode) {
    return PendingIntent.getActivity(
        context,
        requestCode,
        intent,
        PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
  }

  @Nullable
  private static String getApplicationName(
      @Nullable ResolveInfo resolveInfo, PackageManager packageManager) {
    if (resolveInfo == null || resolveInfo.activityInfo == null) {
      return null;
    }
    if ("android".equals(resolveInfo.activityInfo.packageName)) {
      return null;
    }
    if (resolveInfo.activityInfo.applicationInfo == null) {
      return null;
    }
    return packageManager.getApplicationLabel(resolveInfo.activityInfo.applicationInfo).toString();
  }

  private static boolean hasPermission(Context context, ActivityInfo info) {
    if (!info.exported) {
      return false;
    }
    if (info.permission == null) {
      return true;
    }
    return ContextCompat.checkSelfPermission(context, info.permission)
        == PackageManager.PERMISSION_GRANTED;
  }

  /** Data class that holds the result. */
  public static final class Result {
    public final Intent resolvedIntent;
    public final RemoteActionCompat remoteAction;

    public Result(Intent resolvedIntent, RemoteActionCompat remoteAction) {
      this.resolvedIntent = Preconditions.checkNotNull(resolvedIntent);
      this.remoteAction = Preconditions.checkNotNull(remoteAction);
    }
  }

  /**
   * An object to choose a title from resolved info. If {@code null} is returned, {@link
   * #titleWithEntity} will be used if it exists, {@link #titleWithoutEntity} otherwise.
   */
  public interface TitleChooser {
    /**
     * Picks a title from a {@link LabeledIntent} by looking into resolved info. {@code resolveInfo}
     * is guaranteed to have a non-null {@code activityInfo}.
     */
    @Nullable
    CharSequence chooseTitle(LabeledIntent labeledIntent, @Nullable ResolveInfo resolveInfo);
  }
}
