/*
 * Copyright (C) 2016 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.documentsui.files;

import static android.content.ContentResolver.wrap;

import static com.android.documentsui.base.SharedMinimal.DEBUG;

import android.app.DownloadManager;
import android.content.ActivityNotFoundException;
import android.content.ClipData;
import android.content.ContentProviderClient;
import android.content.ContentResolver;
import android.content.Intent;
import android.net.Uri;
import android.os.FileUtils;
import android.provider.DocumentsContract;
import android.text.TextUtils;
import android.util.Log;
import android.view.DragEvent;

import androidx.annotation.VisibleForTesting;
import androidx.fragment.app.FragmentActivity;
import androidx.recyclerview.selection.ItemDetailsLookup.ItemDetails;
import androidx.recyclerview.selection.MutableSelection;
import androidx.recyclerview.selection.Selection;

import com.android.documentsui.AbstractActionHandler;
import com.android.documentsui.ActionModeAddons;
import com.android.documentsui.ActivityConfig;
import com.android.documentsui.DocumentsAccess;
import com.android.documentsui.DocumentsApplication;
import com.android.documentsui.DragAndDropManager;
import com.android.documentsui.Injector;
import com.android.documentsui.MetricConsts;
import com.android.documentsui.Metrics;
import com.android.documentsui.Model;
import com.android.documentsui.R;
import com.android.documentsui.TimeoutTask;
import com.android.documentsui.base.DebugFlags;
import com.android.documentsui.base.DocumentFilters;
import com.android.documentsui.base.DocumentInfo;
import com.android.documentsui.base.DocumentStack;
import com.android.documentsui.base.Features;
import com.android.documentsui.base.Lookup;
import com.android.documentsui.base.MimeTypes;
import com.android.documentsui.base.Providers;
import com.android.documentsui.base.RootInfo;
import com.android.documentsui.base.Shared;
import com.android.documentsui.base.State;
import com.android.documentsui.clipping.ClipStore;
import com.android.documentsui.clipping.DocumentClipper;
import com.android.documentsui.clipping.UrisSupplier;
import com.android.documentsui.dirlist.AnimationView;
import com.android.documentsui.files.ActionHandler.Addons;
import com.android.documentsui.inspector.InspectorActivity;
import com.android.documentsui.queries.SearchViewManager;
import com.android.documentsui.roots.ProvidersAccess;
import com.android.documentsui.services.FileOperation;
import com.android.documentsui.services.FileOperationService;
import com.android.documentsui.services.FileOperations;
import com.android.documentsui.ui.DialogController;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;

import javax.annotation.Nullable;

/**
 * Provides {@link FilesActivity} action specializations to fragments.
 */
public class ActionHandler<T extends FragmentActivity & Addons> extends AbstractActionHandler<T> {

    private static final String TAG = "ManagerActionHandler";
    private static final int SHARE_FILES_COUNT_LIMIT = 100;

    private final ActionModeAddons mActionModeAddons;
    private final Features mFeatures;
    private final ActivityConfig mConfig;
    private final DialogController mDialogs;
    private final DocumentClipper mClipper;
    private final ClipStore mClipStore;
    private final DragAndDropManager mDragAndDropManager;
    private final Model mModel;

    ActionHandler(
            T activity,
            State state,
            ProvidersAccess providers,
            DocumentsAccess docs,
            SearchViewManager searchMgr,
            Lookup<String, Executor> executors,
            ActionModeAddons actionModeAddons,
            DocumentClipper clipper,
            ClipStore clipStore,
            DragAndDropManager dragAndDropManager,
            Injector injector) {

        super(activity, state, providers, docs, searchMgr, executors, injector);

        mActionModeAddons = actionModeAddons;
        mFeatures = injector.features;
        mConfig = injector.config;
        mDialogs = injector.dialogs;
        mClipper = clipper;
        mClipStore = clipStore;
        mDragAndDropManager = dragAndDropManager;
        mModel = injector.getModel();
    }

    @Override
    public boolean dropOn(DragEvent event, RootInfo root) {
        if (!root.supportsCreate() || root.isLibrary()) {
            return false;
        }

        // DragEvent gets recycled, so it is possible that by the time the callback is called,
        // event.getLocalState() and event.getClipData() returns null. Thus, we want to save
        // references to ensure they are non null.
        final ClipData clipData = event.getClipData();
        final Object localState = event.getLocalState();

        return mDragAndDropManager.drop(
                clipData, localState, root, this, mDialogs::showFileOperationStatus);
    }

    @Override
    public void openSelectedInNewWindow() {
        Selection<String> selection = getStableSelection();
        if (selection.isEmpty()) {
            return;
        }

        assert(selection.size() == 1);
        DocumentInfo doc = mModel.getDocument(selection.iterator().next());
        assert(doc != null);
        openInNewWindow(new DocumentStack(mState.stack, doc));
    }

    @Override
    public void openSettings(RootInfo root) {
        Metrics.logUserAction(MetricConsts.USER_ACTION_SETTINGS);
        final Intent intent = new Intent(DocumentsContract.ACTION_DOCUMENT_ROOT_SETTINGS);
        intent.setDataAndType(root.getUri(), DocumentsContract.Root.MIME_TYPE_ITEM);
        mActivity.startActivity(intent);
    }

    @Override
    public void pasteIntoFolder(RootInfo root) {
        this.getRootDocument(
                root,
                TimeoutTask.DEFAULT_TIMEOUT,
                (DocumentInfo doc) -> pasteIntoFolder(root, doc));
    }

    private void pasteIntoFolder(RootInfo root, @Nullable DocumentInfo doc) {
        DocumentStack stack = new DocumentStack(root, doc);
        mClipper.copyFromClipboard(doc, stack, mDialogs::showFileOperationStatus);
    }

    @Override
    public @Nullable DocumentInfo renameDocument(String name, DocumentInfo document) {
        ContentResolver resolver = mActivity.getContentResolver();
        ContentProviderClient client = null;

        try {
            client = DocumentsApplication.acquireUnstableProviderOrThrow(
                    resolver, document.derivedUri.getAuthority());
            Uri newUri = DocumentsContract.renameDocument(
                    wrap(client), document.derivedUri, name);
            return DocumentInfo.fromUri(resolver, newUri);
        } catch (Exception e) {
            Log.w(TAG, "Failed to rename file", e);
            return null;
        } finally {
            FileUtils.closeQuietly(client);
        }
    }

    @Override
    public void openRoot(RootInfo root) {
        Metrics.logRootVisited(MetricConsts.FILES_SCOPE, root);
        mActivity.onRootPicked(root);
    }

    @Override
    public boolean openItem(ItemDetails<String> details, @ViewType int type,
            @ViewType int fallback) {
        DocumentInfo doc = mModel.getDocument(details.getSelectionKey());
        if (doc == null) {
            Log.w(TAG, "Can't view item. No Document available for modeId: "
                    + details.getSelectionKey());
            return false;
        }
        mInjector.searchManager.recordHistory();

        return openDocument(doc, type, fallback);
    }

    // TODO: Make this private and make tests call openDocument(DocumentDetails, int, int) instead.
    @VisibleForTesting
    public boolean openDocument(DocumentInfo doc, @ViewType int type, @ViewType int fallback) {
        if (mConfig.isDocumentEnabled(doc.mimeType, doc.flags, mState)) {
            onDocumentPicked(doc, type, fallback);
            mSelectionMgr.clearSelection();
            return !doc.isContainer();
        }
        return false;
    }

    @Override
    public void springOpenDirectory(DocumentInfo doc) {
        assert(doc.isDirectory());
        mActionModeAddons.finishActionMode();
        openContainerDocument(doc);
    }

    private Selection<String> getSelectedOrFocused() {
        final MutableSelection<String> selection = this.getStableSelection();
        if (selection.isEmpty()) {
            String focusModelId = mFocusHandler.getFocusModelId();
            if (focusModelId != null) {
                selection.add(focusModelId);
            }
        }

        return selection;
    }

    @Override
    public void cutToClipboard() {
        Metrics.logUserAction(MetricConsts.USER_ACTION_CUT_CLIPBOARD);
        Selection<String> selection = getSelectedOrFocused();

        if (selection.isEmpty()) {
            return;
        }

        if (mModel.hasDocuments(selection, DocumentFilters.NOT_MOVABLE)) {
            mDialogs.showOperationUnsupported();
            return;
        }

        mSelectionMgr.clearSelection();

        mClipper.clipDocumentsForCut(mModel::getItemUri, selection, mState.stack.peek());

        mDialogs.showDocumentsClipped(selection.size());
    }

    @Override
    public void copyToClipboard() {
        Metrics.logUserAction(MetricConsts.USER_ACTION_COPY_CLIPBOARD);
        Selection<String> selection = getSelectedOrFocused();

        if (selection.isEmpty()) {
            return;
        }
        mSelectionMgr.clearSelection();

        mClipper.clipDocumentsForCopy(mModel::getItemUri, selection);

        mDialogs.showDocumentsClipped(selection.size());
    }

    @Override
    public void viewInOwner() {
        Metrics.logUserAction(MetricConsts.USER_ACTION_VIEW_IN_APPLICATION);
        Selection<String> selection = getSelectedOrFocused();

        if (selection.isEmpty() || selection.size() > 1) {
            return;
        }
        DocumentInfo doc = mModel.getDocument(selection.iterator().next());
        Intent intent = new Intent(DocumentsContract.ACTION_DOCUMENT_SETTINGS);
        intent.setPackage(mProviders.getPackageName(doc.authority));
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        intent.setData(doc.derivedUri);
        try {
            mActivity.startActivity(intent);
        } catch (ActivityNotFoundException e) {
            Log.e(TAG, "Failed to view settings in application for " + doc.derivedUri, e);
            mDialogs.showNoApplicationFound();
        }
    }

    @Override
    public void showDeleteDialog() {
        Selection selection = getSelectedOrFocused();
        if (selection.isEmpty()) {
            return;
        }

        DeleteDocumentFragment.show(mActivity.getSupportFragmentManager(),
                mModel.getDocuments(selection),
                mState.stack.peek());
    }


    @Override
    public void deleteSelectedDocuments(List<DocumentInfo> docs, DocumentInfo srcParent) {
        if (docs == null || docs.isEmpty()) {
            return;
        }

        mActionModeAddons.finishActionMode();

        List<Uri> uris = new ArrayList<>(docs.size());
        for (DocumentInfo doc : docs) {
            uris.add(doc.derivedUri);
        }

        UrisSupplier srcs;
        try {
            srcs = UrisSupplier.create(
                    uris,
                    mClipStore);
        } catch (Exception e) {
            Log.e(TAG, "Failed to delete a file because we were unable to get item URIs.", e);
            mDialogs.showFileOperationStatus(
                    FileOperations.Callback.STATUS_FAILED,
                    FileOperationService.OPERATION_DELETE,
                    uris.size());
            return;
        }

        FileOperation operation = new FileOperation.Builder()
                .withOpType(FileOperationService.OPERATION_DELETE)
                .withDestination(mState.stack)
                .withSrcs(srcs)
                .withSrcParent(srcParent == null ? null : srcParent.derivedUri)
                .build();

        FileOperations.start(mActivity, operation, mDialogs::showFileOperationStatus,
                FileOperations.createJobId());
    }

    @Override
    public void shareSelectedDocuments() {
        Metrics.logUserAction(MetricConsts.USER_ACTION_SHARE);

        Selection<String> selection = getStableSelection();
        if (selection.isEmpty()) {
            return;
        } else if (selection.size() > SHARE_FILES_COUNT_LIMIT) {
            mDialogs.showShareOverLimit(SHARE_FILES_COUNT_LIMIT);
            return;
        }

        // Model must be accessed in UI thread, since underlying cursor is not threadsafe.
        List<DocumentInfo> docs = mModel.loadDocuments(
                selection, DocumentFilters.sharable(mFeatures));

        Intent intent;

        if (docs.size() == 1) {
            intent = new Intent(Intent.ACTION_SEND);
            DocumentInfo doc = docs.get(0);
            intent.setType(doc.mimeType);
            intent.putExtra(Intent.EXTRA_STREAM, doc.derivedUri);

        } else if (docs.size() > 1) {
            intent = new Intent(Intent.ACTION_SEND_MULTIPLE);

            final ArrayList<String> mimeTypes = new ArrayList<>();
            final ArrayList<Uri> uris = new ArrayList<>();
            for (DocumentInfo doc : docs) {
                mimeTypes.add(doc.mimeType);
                uris.add(doc.derivedUri);
            }

            intent.setType(MimeTypes.findCommonMimeType(mimeTypes));
            intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);

        } else {
            // Everything filtered out, nothing to share.
            return;
        }

        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        intent.addCategory(Intent.CATEGORY_DEFAULT);

        if (mFeatures.isVirtualFilesSharingEnabled()
                && mModel.hasDocuments(selection, DocumentFilters.VIRTUAL)) {
            intent.addCategory(Intent.CATEGORY_TYPED_OPENABLE);
        }

        Intent chooserIntent = Intent.createChooser(
                intent, mActivity.getResources().getText(R.string.share_via));

        mActivity.startActivity(chooserIntent);
    }

    @Override
    public void loadDocumentsForCurrentStack() {
        super.loadDocumentsForCurrentStack();
    }

    @Override
    public void initLocation(Intent intent) {
        assert(intent != null);

        // stack is initialized if it's restored from bundle, which means we're restoring a
        // previously stored state.
        if (mState.stack.isInitialized()) {
            if (DEBUG) {
                Log.d(TAG, "Stack already resolved for uri: " + intent.getData());
            }
            restoreRootAndDirectory();
            return;
        }

        if (launchToStackLocation(intent)) {
            if (DEBUG) {
                Log.d(TAG, "Launched to location from stack.");
            }
            return;
        }

        if (launchToRoot(intent)) {
            if (DEBUG) {
                Log.d(TAG, "Launched to root for browsing.");
            }
            return;
        }

        if (launchToDocument(intent)) {
            if (DEBUG) {
                Log.d(TAG, "Launched to a document.");
            }
            return;
        }

        if (launchToDownloads(intent)) {
            if (DEBUG) {
                Log.d(TAG, "Launched to a downloads.");
            }
            return;
        }

        if (DEBUG) {
            Log.d(TAG, "Launching directly into Home directory.");
        }
        launchToDefaultLocation();
    }

    @Override
    protected void launchToDefaultLocation() {
        if (mFeatures.isDefaultRootInBrowseEnabled()) {
            loadHomeDir();
        } else {
            loadRecent();
        }
    }

    // If EXTRA_STACK is not null in intent, we'll skip other means of loading
    // or restoring the stack (like URI).
    //
    // When restoring from a stack, if a URI is present, it should only ever be:
    // -- a launch URI: Launch URIs support sensible activity management,
    //    but don't specify a real content target)
    // -- a fake Uri from notifications. These URIs have no authority (TODO: details).
    //
    // Any other URI is *sorta* unexpected...except when browsing an archive
    // in downloads.
    private boolean launchToStackLocation(Intent intent) {
        DocumentStack stack = intent.getParcelableExtra(Shared.EXTRA_STACK);
        if (stack == null || stack.getRoot() == null) {
            return false;
        }

        mState.stack.reset(stack);
        if (mState.stack.isEmpty()) {
            mActivity.onRootPicked(mState.stack.getRoot());
        } else {
            mActivity.refreshCurrentRootAndDirectory(AnimationView.ANIM_NONE);
        }

        return true;
    }

    private boolean launchToRoot(Intent intent) {
        String action = intent.getAction();
        if (Intent.ACTION_VIEW.equals(action)) {
            Uri uri = intent.getData();
            if (DocumentsContract.isRootUri(mActivity, uri)) {
                if (DEBUG) {
                    Log.d(TAG, "Launching with root URI.");
                }
                // If we've got a specific root to display, restore that root using a dedicated
                // authority. That way a misbehaving provider won't result in an ANR.
                loadRoot(uri);
                return true;
            } else if (DocumentsContract.isRootsUri(mActivity, uri)) {
                if (DEBUG) {
                    Log.d(TAG, "Launching first root with roots URI.");
                }
                // TODO: b/116760996 Let the user can disambiguate between roots if there are
                // multiple from DocumentsProvider instead of launching the first root in default
                loadFirstRoot(uri);
                return true;
            }
        }
        return false;
    }

    private boolean launchToDocument(Intent intent) {
        if (Intent.ACTION_VIEW.equals(intent.getAction())) {
            Uri uri = intent.getData();
            if (DocumentsContract.isDocumentUri(mActivity, uri)) {
                return launchToDocument(intent.getData());
            }
        }

        return false;
    }

    private boolean launchToDownloads(Intent intent) {
        if (DownloadManager.ACTION_VIEW_DOWNLOADS.equals(intent.getAction())) {
            Uri uri = DocumentsContract.buildRootUri(Providers.AUTHORITY_DOWNLOADS,
                    Providers.ROOT_ID_DOWNLOADS);
            loadRoot(uri);
            return true;
        }

        return false;
    }

    @Override
    public void showChooserForDoc(DocumentInfo doc) {
        assert(!doc.isDirectory());

        if (manageDocument(doc)) {
            Log.w(TAG, "Open with is not yet supported for managed doc.");
            return;
        }

        Intent intent = Intent.createChooser(buildViewIntent(doc), null);
        intent.putExtra(Intent.EXTRA_AUTO_LAUNCH_SINGLE_CHOICE, false);
        try {
            mActivity.startActivity(intent);
        } catch (ActivityNotFoundException e) {
            mDialogs.showNoApplicationFound();
        }
    }

    private void onDocumentPicked(DocumentInfo doc, @ViewType int type, @ViewType int fallback) {
        if (doc.isContainer()) {
            openContainerDocument(doc);
            return;
        }

        if (manageDocument(doc)) {
            return;
        }

        // For APKs, even if the type is preview, we send an ACTION_VIEW intent to allow
        // PackageManager to install it.  This allows users to install APKs from any root.
        // The Downloads special case is handled above in #manageDocument.
        if (MimeTypes.isApkType(doc.mimeType)) {
            viewDocument(doc);
            return;
        }

        switch (type) {
          case VIEW_TYPE_REGULAR:
            if (viewDocument(doc)) {
                return;
            }
            break;

          case VIEW_TYPE_PREVIEW:
            if (previewDocument(doc)) {
                return;
            }
            break;

          default:
            throw new IllegalArgumentException("Illegal view type.");
        }

        switch (fallback) {
          case VIEW_TYPE_REGULAR:
            if (viewDocument(doc)) {
                return;
            }
            break;

          case VIEW_TYPE_PREVIEW:
            if (previewDocument(doc)) {
                return;
            }
            break;

          case VIEW_TYPE_NONE:
            break;

          default:
            throw new IllegalArgumentException("Illegal fallback view type.");
        }

        // Failed to view including fallback, and it's in an archive.
        if (type != VIEW_TYPE_NONE && fallback != VIEW_TYPE_NONE && doc.isInArchive()) {
            mDialogs.showViewInArchivesUnsupported();
        }
    }

    private boolean viewDocument(DocumentInfo doc) {
        if (doc.isPartial()) {
            Log.w(TAG, "Can't view partial file.");
            return false;
        }

        if (doc.isInArchive()) {
            Log.w(TAG, "Can't view files in archives.");
            return false;
        }

        if (doc.isDirectory()) {
            Log.w(TAG, "Can't view directories.");
            return true;
        }

        Intent intent = buildViewIntent(doc);
        if (DEBUG && intent.getClipData() != null) {
            Log.d(TAG, "Starting intent w/ clip data: " + intent.getClipData());
        }

        try {
            mActivity.startActivity(intent);
            return true;
        } catch (ActivityNotFoundException e) {
            mDialogs.showNoApplicationFound();
        }
        return false;
    }

    private boolean previewDocument(DocumentInfo doc) {
        if (doc.isPartial()) {
            Log.w(TAG, "Can't view partial file.");
            return false;
        }

        Intent intent = new QuickViewIntentBuilder(
                mActivity.getPackageManager(),
                mActivity.getResources(),
                doc,
                mModel,
                false /* fromPicker */).build();

        if (intent != null) {
            // TODO: un-work around issue b/24963914. Should be fixed soon.
            try {
                mActivity.startActivity(intent);
                return true;
            } catch (SecurityException e) {
                // Carry on to regular view mode.
                Log.e(TAG, "Caught security error: " + e.getLocalizedMessage());
            }
        }

        return false;
    }

    private boolean manageDocument(DocumentInfo doc) {
        if (isManagedDownload(doc)) {
            // First try managing the document; we expect manager to filter
            // based on authority, so we don't grant.
            Intent manage = new Intent(DocumentsContract.ACTION_MANAGE_DOCUMENT);
            manage.setData(doc.derivedUri);
            try {
                mActivity.startActivity(manage);
                return true;
            } catch (ActivityNotFoundException ex) {
                // Fall back to regular handling.
            }
        }

        return false;
    }

    private boolean isManagedDownload(DocumentInfo doc) {
        // Anything on downloads goes through the back through downloads manager
        // (that's the MANAGE_DOCUMENT bit).
        // This is done for two reasons:
        // 1) The file in question might be a failed/queued or otherwise have some
        //    specialized download handling.
        // 2) For APKs, the download manager will add on some important security stuff
        //    like origin URL.
        // 3) For partial files, the download manager will offer to restart/retry downloads.

        // All other files not on downloads, event APKs, would get no benefit from this
        // treatment, thusly the "isDownloads" check.

        // Launch MANAGE_DOCUMENTS only for the root level files, so it's not called for
        // files in archives or in child folders. Also, if the activity is already browsing
        // a ZIP from downloads, then skip MANAGE_DOCUMENTS.
        if (Intent.ACTION_VIEW.equals(mActivity.getIntent().getAction())
                && mState.stack.size() > 1) {
            // viewing the contents of an archive.
            return false;
        }

        // management is only supported in Downloads root or downloaded files show in Recent root.
        if (Providers.AUTHORITY_DOWNLOADS.equals(doc.authority)) {
            // only on APKs or partial files.
            return MimeTypes.isApkType(doc.mimeType) || doc.isPartial();
        }

        return false;
    }

    private Intent buildViewIntent(DocumentInfo doc) {
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setDataAndType(doc.derivedUri, doc.mimeType);

        // Downloads has traditionally added the WRITE permission
        // in the TrampolineActivity. Since this behavior is long
        // established, we set the same permission for non-managed files
        // This ensures consistent behavior between the Downloads root
        // and other roots.
        int flags = Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_ACTIVITY_SINGLE_TOP;
        if (doc.isWriteSupported()) {
            flags |= Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
        }
        intent.setFlags(flags);

        return intent;
    }

    @Override
    public void showInspector(DocumentInfo doc) {
        Metrics.logUserAction(MetricConsts.USER_ACTION_INSPECTOR);
        Intent intent = new Intent(mActivity, InspectorActivity.class);
        intent.setData(doc.derivedUri);

        // permit the display of debug info about the file.
        intent.putExtra(
                Shared.EXTRA_SHOW_DEBUG,
                mFeatures.isDebugSupportEnabled() &&
                        (DEBUG || DebugFlags.getDocumentDetailsEnabled()));

        // The "root document" (top level folder in a root) don't usually have a
        // human friendly display name. That's because we've never shown the root
        // folder's name to anyone.
        // For that reason when the doc being inspected is the root folder,
        // we override the displayName of the doc w/ the Root's name instead.
        // The Root's name is shown to the user in the sidebar.
        if (doc.isDirectory() && mState.stack.size() == 1 && mState.stack.get(0).equals(doc)) {
            RootInfo root = mActivity.getCurrentRoot();
            // Recents root title isn't defined, but inspector is disabled for recents root folder.
            assert !TextUtils.isEmpty(root.title);
            intent.putExtra(Intent.EXTRA_TITLE, root.title);
        }
        mActivity.startActivity(intent);
    }

    public interface Addons extends CommonAddons {
    }
}
