/*
 * Copyright (C) 2020 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.example.android.inlinefillservice;

import android.app.PendingIntent;
import android.app.slice.Slice;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Icon;
import android.service.autofill.Dataset;
import android.service.autofill.FillRequest;
import android.service.autofill.InlinePresentation;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.view.autofill.AutofillId;
import android.view.inputmethod.InlineSuggestionsRequest;
import android.widget.inline.InlinePresentationSpec;

import androidx.autofill.inline.v1.InlineSuggestionUi;
import androidx.autofill.inline.v1.InlineSuggestionUi.Content;

import java.util.Optional;

public class InlineRequestHelper {
    static Optional<InlineSuggestionsRequest> getInlineSuggestionsRequest(FillRequest request) {
        final InlineSuggestionsRequest inlineRequest = request.getInlineSuggestionsRequest();
        if (inlineRequest != null && inlineRequest.getMaxSuggestionCount() > 0
                && !inlineRequest.getInlinePresentationSpecs().isEmpty()) {
            return Optional.of(inlineRequest);
        }
        return Optional.empty();
    }

    static int getMaxSuggestionCount(Optional<InlineSuggestionsRequest> inlineRequest, int max) {
        if (inlineRequest.isPresent()) {
            return Math.min(max, inlineRequest.get().getMaxSuggestionCount());
        }
        return max;
    }

    static InlinePresentation maybeCreateInlineAuthenticationResponse(
            Context context, Optional<InlineSuggestionsRequest> inlineRequest) {
        if (!inlineRequest.isPresent()) {
            return null;
        }
        final PendingIntent attribution = createAttribution(context,
                "Please tap on the chip to authenticate the Autofill response.");
        final Slice slice = createSlice("Tap to auth response", null, null, null, attribution);
        final InlinePresentationSpec spec = inlineRequest.get().getInlinePresentationSpecs().get(0);
        return new InlinePresentation(slice, spec, false);
    }

    static InlinePresentation createInlineDataset(Context context,
            InlineSuggestionsRequest inlineRequest, String value, int index) {
        final PendingIntent attribution = createAttribution(context,
                "Please tap on the chip to autofill the value:" + value);
        final Slice slice = createSlice(value, null, null, null, attribution);
        index = Math.min(inlineRequest.getInlinePresentationSpecs().size() - 1, index);
        final InlinePresentationSpec spec = inlineRequest.getInlinePresentationSpecs().get(index);
        return new InlinePresentation(slice, spec, false);
    }

    static Dataset createInlineActionDataset(Context context,
            ArrayMap<String, AutofillId> fields,
            InlineSuggestionsRequest inlineRequest, int drawable) {
        PendingIntent pendingIntent =
                PendingIntent.getActivity(context, 0, new Intent(context, SettingsActivity.class),
                        PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);

        Dataset.Builder builder =
                new Dataset.Builder()
                        .setInlinePresentation(createInlineAction(context, inlineRequest, drawable))
                        .setAuthentication(pendingIntent.getIntentSender());
        for (AutofillId fieldId : fields.values()) {
            builder.setValue(fieldId, null);
        }
        return builder.build();
    }

    private static InlinePresentation createInlineAction(Context context,
            InlineSuggestionsRequest inlineRequest, int drawable) {
        final PendingIntent attribution = createAttribution(context,
                "Please tap on the chip to launch the action.");
        final Icon icon = Icon.createWithResource(context, drawable);
        final Slice slice = createSlice(null, null, icon, null, attribution);
        // Reuse the first spec's height for the inline action size, as there isn't dedicated
        // value from the request for this.
        final InlinePresentationSpec spec = inlineRequest.getInlinePresentationSpecs().get(0);
        return new InlinePresentation(slice, spec, true);
    }

    private static Slice createSlice(
            String title, String subtitle, Icon startIcon, Icon endIcon,
            PendingIntent attribution) {
        Content.Builder builder = InlineSuggestionUi.newContentBuilder(attribution);
        if (!TextUtils.isEmpty(title)) {
            builder.setTitle(title);
        }
        if (!TextUtils.isEmpty(subtitle)) {
            builder.setSubtitle(subtitle);
        }
        if (startIcon != null) {
            builder.setStartIcon(startIcon);
        }
        if (endIcon != null) {
            builder.setEndIcon(endIcon);
        }
        return builder.build().getSlice();
    }

    private static PendingIntent createAttribution(Context context, String msg) {
        Intent intent = new Intent(context, AttributionDialogActivity.class);
        intent.putExtra(AttributionDialogActivity.KEY_MSG, msg);
        // Should use different request code to avoid the new intent overriding the old one.
        PendingIntent pendingIntent = PendingIntent.getActivity(context, msg.hashCode(), intent,
                PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
        return pendingIntent;
    }

}
