/*
 * Copyright 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 android.view.textclassifier;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.text.Spannable;
import android.text.style.ClickableSpan;
import android.text.util.Linkify;
import android.text.util.Linkify.LinkifyMask;
import android.view.textclassifier.TextLinks.TextLink;
import android.view.textclassifier.TextLinks.TextLinkSpan;

import com.android.internal.util.Preconditions;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;

/**
 * Parameters for generating and applying links.
 * @hide
 */
public final class TextLinksParams {

    /**
     * A function to create spans from TextLinks.
     */
    private static final Function<TextLink, TextLinkSpan> DEFAULT_SPAN_FACTORY =
            textLink -> new TextLinkSpan(textLink);

    @TextLinks.ApplyStrategy
    private final int mApplyStrategy;
    private final Function<TextLink, TextLinkSpan> mSpanFactory;
    private final TextClassifier.EntityConfig mEntityConfig;

    private TextLinksParams(
            @TextLinks.ApplyStrategy int applyStrategy,
            Function<TextLink, TextLinkSpan> spanFactory) {
        mApplyStrategy = applyStrategy;
        mSpanFactory = spanFactory;
        mEntityConfig = TextClassifier.EntityConfig.createWithHints(null);
    }

    /**
     * Returns a new TextLinksParams object based on the specified link mask.
     *
     * @param mask the link mask
     *      e.g. {@link LinkifyMask#PHONE_NUMBERS} | {@link LinkifyMask#EMAIL_ADDRESSES}
     * @hide
     */
    @NonNull
    public static TextLinksParams fromLinkMask(@LinkifyMask int mask) {
        final List<String> entitiesToFind = new ArrayList<>();
        if ((mask & Linkify.WEB_URLS) != 0) {
            entitiesToFind.add(TextClassifier.TYPE_URL);
        }
        if ((mask & Linkify.EMAIL_ADDRESSES) != 0) {
            entitiesToFind.add(TextClassifier.TYPE_EMAIL);
        }
        if ((mask & Linkify.PHONE_NUMBERS) != 0) {
            entitiesToFind.add(TextClassifier.TYPE_PHONE);
        }
        if ((mask & Linkify.MAP_ADDRESSES) != 0) {
            entitiesToFind.add(TextClassifier.TYPE_ADDRESS);
        }
        return new TextLinksParams.Builder().setEntityConfig(
                TextClassifier.EntityConfig.createWithExplicitEntityList(entitiesToFind))
                .build();
    }

    /**
     * Returns the entity config used to determine what entity types to generate.
     */
    @NonNull
    public TextClassifier.EntityConfig getEntityConfig() {
        return mEntityConfig;
    }

    /**
     * Annotates the given text with the generated links. It will fail if the provided text doesn't
     * match the original text used to crete the TextLinks.
     *
     * @param text the text to apply the links to. Must match the original text
     * @param textLinks the links to apply to the text
     *
     * @return a status code indicating whether or not the links were successfully applied
     * @hide
     */
    @TextLinks.Status
    public int apply(@NonNull Spannable text, @NonNull TextLinks textLinks) {
        Preconditions.checkNotNull(text);
        Preconditions.checkNotNull(textLinks);

        final String textString = text.toString();
        if (!textString.startsWith(textLinks.getText())) {
            return TextLinks.STATUS_DIFFERENT_TEXT;
        }
        if (textLinks.getLinks().isEmpty()) {
            return TextLinks.STATUS_NO_LINKS_FOUND;
        }

        int applyCount = 0;
        for (TextLink link : textLinks.getLinks()) {
            final TextLinkSpan span = mSpanFactory.apply(link);
            if (span != null) {
                final ClickableSpan[] existingSpans = text.getSpans(
                        link.getStart(), link.getEnd(), ClickableSpan.class);
                if (existingSpans.length > 0) {
                    if (mApplyStrategy == TextLinks.APPLY_STRATEGY_REPLACE) {
                        for (ClickableSpan existingSpan : existingSpans) {
                            text.removeSpan(existingSpan);
                        }
                        text.setSpan(span, link.getStart(), link.getEnd(),
                                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                        applyCount++;
                    }
                } else {
                    text.setSpan(span, link.getStart(), link.getEnd(),
                            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                    applyCount++;
                }
            }
        }
        if (applyCount == 0) {
            return TextLinks.STATUS_NO_LINKS_APPLIED;
        }
        return TextLinks.STATUS_LINKS_APPLIED;
    }

    /**
     * A builder for building TextLinksParams.
     */
    public static final class Builder {

        @TextLinks.ApplyStrategy
        private int mApplyStrategy = TextLinks.APPLY_STRATEGY_IGNORE;
        private Function<TextLink, TextLinkSpan> mSpanFactory = DEFAULT_SPAN_FACTORY;

        /**
         * Sets the apply strategy used to determine how to apply links to text.
         *      e.g {@link TextLinks#APPLY_STRATEGY_IGNORE}
         *
         * @return this builder
         */
        public Builder setApplyStrategy(@TextLinks.ApplyStrategy int applyStrategy) {
            mApplyStrategy = checkApplyStrategy(applyStrategy);
            return this;
        }

        /**
         * Sets a custom span factory for converting TextLinks to TextLinkSpans.
         * Set to {@code null} to use the default span factory.
         *
         * @return this builder
         */
        public Builder setSpanFactory(@Nullable Function<TextLink, TextLinkSpan> spanFactory) {
            mSpanFactory = spanFactory == null ? DEFAULT_SPAN_FACTORY : spanFactory;
            return this;
        }

        /**
         * Sets the entity configuration used to determine what entity types to generate.
         * Set to {@code null} for the default entity config which will automatically determine
         * what links to generate.
         *
         * @return this builder
         */
        public Builder setEntityConfig(@Nullable TextClassifier.EntityConfig entityConfig) {
            return this;
        }

        /**
         * Builds and returns a TextLinksParams object.
         */
        public TextLinksParams build() {
            return new TextLinksParams(mApplyStrategy, mSpanFactory);
        }
    }

    /** @throws IllegalArgumentException if the value is invalid */
    @TextLinks.ApplyStrategy
    private static int checkApplyStrategy(int applyStrategy) {
        if (applyStrategy != TextLinks.APPLY_STRATEGY_IGNORE
                && applyStrategy != TextLinks.APPLY_STRATEGY_REPLACE) {
            throw new IllegalArgumentException(
                    "Invalid apply strategy. See TextLinksParams.ApplyStrategy for options.");
        }
        return applyStrategy;
    }
}

