/*
 * Copyright (C) 2017 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.content.Context;
import android.metrics.LogMaker;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;

import java.text.BreakIterator;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.StringJoiner;

/**
 * A helper for logging selection session events.
 * @hide
 */
public final class SelectionSessionLogger {

    private static final String LOG_TAG = "SelectionSessionLogger";
    static final String CLASSIFIER_ID = "androidtc";

    private static final int START_EVENT_DELTA = MetricsEvent.FIELD_SELECTION_SINCE_START;
    private static final int PREV_EVENT_DELTA = MetricsEvent.FIELD_SELECTION_SINCE_PREVIOUS;
    private static final int INDEX = MetricsEvent.FIELD_SELECTION_SESSION_INDEX;
    private static final int WIDGET_TYPE = MetricsEvent.FIELD_SELECTION_WIDGET_TYPE;
    private static final int WIDGET_VERSION = MetricsEvent.FIELD_SELECTION_WIDGET_VERSION;
    private static final int MODEL_NAME = MetricsEvent.FIELD_TEXTCLASSIFIER_MODEL;
    private static final int ENTITY_TYPE = MetricsEvent.FIELD_SELECTION_ENTITY_TYPE;
    private static final int SMART_START = MetricsEvent.FIELD_SELECTION_SMART_RANGE_START;
    private static final int SMART_END = MetricsEvent.FIELD_SELECTION_SMART_RANGE_END;
    private static final int EVENT_START = MetricsEvent.FIELD_SELECTION_RANGE_START;
    private static final int EVENT_END = MetricsEvent.FIELD_SELECTION_RANGE_END;
    private static final int SESSION_ID = MetricsEvent.FIELD_SELECTION_SESSION_ID;

    private static final String ZERO = "0";
    private static final String UNKNOWN = "unknown";

    private final MetricsLogger mMetricsLogger;

    public SelectionSessionLogger() {
        mMetricsLogger = new MetricsLogger();
    }

    @VisibleForTesting
    public SelectionSessionLogger(@NonNull MetricsLogger metricsLogger) {
        mMetricsLogger = Objects.requireNonNull(metricsLogger);
    }

    /** Emits a selection event to the logs. */
    public void writeEvent(@NonNull SelectionEvent event) {
        Objects.requireNonNull(event);
        final LogMaker log = new LogMaker(MetricsEvent.TEXT_SELECTION_SESSION)
                .setType(getLogType(event))
                .setSubtype(getLogSubType(event))
                .setPackageName(event.getPackageName())
                .addTaggedData(START_EVENT_DELTA, event.getDurationSinceSessionStart())
                .addTaggedData(PREV_EVENT_DELTA, event.getDurationSincePreviousEvent())
                .addTaggedData(INDEX, event.getEventIndex())
                .addTaggedData(WIDGET_TYPE, event.getWidgetType())
                .addTaggedData(WIDGET_VERSION, event.getWidgetVersion())
                .addTaggedData(ENTITY_TYPE, event.getEntityType())
                .addTaggedData(EVENT_START, event.getStart())
                .addTaggedData(EVENT_END, event.getEnd());
        if (isPlatformLocalTextClassifierSmartSelection(event.getResultId())) {
            // Ensure result id and smart indices are only set for events with smart selection from
            // the platform's textclassifier.
            log.addTaggedData(MODEL_NAME, SignatureParser.getModelName(event.getResultId()))
                    .addTaggedData(SMART_START, event.getSmartStart())
                    .addTaggedData(SMART_END, event.getSmartEnd());
        }
        if (event.getSessionId() != null) {
            log.addTaggedData(SESSION_ID, event.getSessionId().getValue());
        }
        mMetricsLogger.write(log);
        debugLog(log);
    }

    private static int getLogType(SelectionEvent event) {
        switch (event.getEventType()) {
            case SelectionEvent.ACTION_OVERTYPE:
                return MetricsEvent.ACTION_TEXT_SELECTION_OVERTYPE;
            case SelectionEvent.ACTION_COPY:
                return MetricsEvent.ACTION_TEXT_SELECTION_COPY;
            case SelectionEvent.ACTION_PASTE:
                return MetricsEvent.ACTION_TEXT_SELECTION_PASTE;
            case SelectionEvent.ACTION_CUT:
                return MetricsEvent.ACTION_TEXT_SELECTION_CUT;
            case SelectionEvent.ACTION_SHARE:
                return MetricsEvent.ACTION_TEXT_SELECTION_SHARE;
            case SelectionEvent.ACTION_SMART_SHARE:
                return MetricsEvent.ACTION_TEXT_SELECTION_SMART_SHARE;
            case SelectionEvent.ACTION_DRAG:
                return MetricsEvent.ACTION_TEXT_SELECTION_DRAG;
            case SelectionEvent.ACTION_ABANDON:
                return MetricsEvent.ACTION_TEXT_SELECTION_ABANDON;
            case SelectionEvent.ACTION_OTHER:
                return MetricsEvent.ACTION_TEXT_SELECTION_OTHER;
            case SelectionEvent.ACTION_SELECT_ALL:
                return MetricsEvent.ACTION_TEXT_SELECTION_SELECT_ALL;
            case SelectionEvent.ACTION_RESET:
                return MetricsEvent.ACTION_TEXT_SELECTION_RESET;
            case SelectionEvent.EVENT_SELECTION_STARTED:
                return MetricsEvent.ACTION_TEXT_SELECTION_START;
            case SelectionEvent.EVENT_SELECTION_MODIFIED:
                return MetricsEvent.ACTION_TEXT_SELECTION_MODIFY;
            case SelectionEvent.EVENT_SMART_SELECTION_SINGLE:
                return MetricsEvent.ACTION_TEXT_SELECTION_SMART_SINGLE;
            case SelectionEvent.EVENT_SMART_SELECTION_MULTI:
                return MetricsEvent.ACTION_TEXT_SELECTION_SMART_MULTI;
            case SelectionEvent.EVENT_AUTO_SELECTION:
                return MetricsEvent.ACTION_TEXT_SELECTION_AUTO;
            default:
                return MetricsEvent.VIEW_UNKNOWN;
        }
    }

    private static int getLogSubType(SelectionEvent event) {
        switch (event.getInvocationMethod()) {
            case SelectionEvent.INVOCATION_MANUAL:
                return MetricsEvent.TEXT_SELECTION_INVOCATION_MANUAL;
            case SelectionEvent.INVOCATION_LINK:
                return MetricsEvent.TEXT_SELECTION_INVOCATION_LINK;
            default:
                return MetricsEvent.TEXT_SELECTION_INVOCATION_UNKNOWN;
        }
    }

    private static String getLogTypeString(int logType) {
        switch (logType) {
            case MetricsEvent.ACTION_TEXT_SELECTION_OVERTYPE:
                return "OVERTYPE";
            case MetricsEvent.ACTION_TEXT_SELECTION_COPY:
                return "COPY";
            case MetricsEvent.ACTION_TEXT_SELECTION_PASTE:
                return "PASTE";
            case MetricsEvent.ACTION_TEXT_SELECTION_CUT:
                return "CUT";
            case MetricsEvent.ACTION_TEXT_SELECTION_SHARE:
                return "SHARE";
            case MetricsEvent.ACTION_TEXT_SELECTION_SMART_SHARE:
                return "SMART_SHARE";
            case MetricsEvent.ACTION_TEXT_SELECTION_DRAG:
                return "DRAG";
            case MetricsEvent.ACTION_TEXT_SELECTION_ABANDON:
                return "ABANDON";
            case MetricsEvent.ACTION_TEXT_SELECTION_OTHER:
                return "OTHER";
            case MetricsEvent.ACTION_TEXT_SELECTION_SELECT_ALL:
                return "SELECT_ALL";
            case MetricsEvent.ACTION_TEXT_SELECTION_RESET:
                return "RESET";
            case MetricsEvent.ACTION_TEXT_SELECTION_START:
                return "SELECTION_STARTED";
            case MetricsEvent.ACTION_TEXT_SELECTION_MODIFY:
                return "SELECTION_MODIFIED";
            case MetricsEvent.ACTION_TEXT_SELECTION_SMART_SINGLE:
                return "SMART_SELECTION_SINGLE";
            case MetricsEvent.ACTION_TEXT_SELECTION_SMART_MULTI:
                return "SMART_SELECTION_MULTI";
            case MetricsEvent.ACTION_TEXT_SELECTION_AUTO:
                return "AUTO_SELECTION";
            default:
                return UNKNOWN;
        }
    }

    private static String getLogSubTypeString(int logSubType) {
        switch (logSubType) {
            case MetricsEvent.TEXT_SELECTION_INVOCATION_MANUAL:
                return "MANUAL";
            case MetricsEvent.TEXT_SELECTION_INVOCATION_LINK:
                return "LINK";
            default:
                return UNKNOWN;
        }
    }

    static boolean isPlatformLocalTextClassifierSmartSelection(String signature) {
        return SelectionSessionLogger.CLASSIFIER_ID.equals(
                SelectionSessionLogger.SignatureParser.getClassifierId(signature));
    }

    private static void debugLog(LogMaker log) {
        if (!Log.ENABLE_FULL_LOGGING) {
            return;
        }
        final String widgetType = Objects.toString(log.getTaggedData(WIDGET_TYPE), UNKNOWN);
        final String widgetVersion = Objects.toString(log.getTaggedData(WIDGET_VERSION), "");
        final String widget = widgetVersion.isEmpty()
                ? widgetType : widgetType + "-" + widgetVersion;
        final int index = Integer.parseInt(Objects.toString(log.getTaggedData(INDEX), ZERO));
        if (log.getType() == MetricsEvent.ACTION_TEXT_SELECTION_START) {
            String sessionId = Objects.toString(log.getTaggedData(SESSION_ID), "");
            sessionId = sessionId.substring(sessionId.lastIndexOf("-") + 1);
            Log.d(LOG_TAG, String.format("New selection session: %s (%s)", widget, sessionId));
        }

        final String model = Objects.toString(log.getTaggedData(MODEL_NAME), UNKNOWN);
        final String entity = Objects.toString(log.getTaggedData(ENTITY_TYPE), UNKNOWN);
        final String type = getLogTypeString(log.getType());
        final String subType = getLogSubTypeString(log.getSubtype());
        final int smartStart = Integer.parseInt(
                Objects.toString(log.getTaggedData(SMART_START), ZERO));
        final int smartEnd = Integer.parseInt(
                Objects.toString(log.getTaggedData(SMART_END), ZERO));
        final int eventStart = Integer.parseInt(
                Objects.toString(log.getTaggedData(EVENT_START), ZERO));
        final int eventEnd = Integer.parseInt(
                Objects.toString(log.getTaggedData(EVENT_END), ZERO));

        Log.v(LOG_TAG,
                String.format(Locale.US, "%2d: %s/%s/%s, range=%d,%d - smart_range=%d,%d (%s/%s)",
                        index, type, subType, entity, eventStart, eventEnd, smartStart, smartEnd,
                        widget, model));
    }

    /**
     * Returns a token iterator for tokenizing text for logging purposes.
     */
    public static BreakIterator getTokenIterator(@NonNull Locale locale) {
        return BreakIterator.getWordInstance(Objects.requireNonNull(locale));
    }

    /**
     * Creates a string id that may be used to identify a TextClassifier result.
     */
    public static String createId(
            String text, int start, int end, Context context, int modelVersion,
            List<Locale> locales) {
        Objects.requireNonNull(text);
        Objects.requireNonNull(context);
        Objects.requireNonNull(locales);
        final StringJoiner localesJoiner = new StringJoiner(",");
        for (Locale locale : locales) {
            localesJoiner.add(locale.toLanguageTag());
        }
        final String modelName = String.format(Locale.US, "%s_v%d", localesJoiner.toString(),
                modelVersion);
        final int hash = Objects.hash(text, start, end, context.getPackageName());
        return SignatureParser.createSignature(CLASSIFIER_ID, modelName, hash);
    }

    /**
     * Helper for creating and parsing string ids for
     * {@link android.view.textclassifier.TextClassifierImpl}.
     */
    @VisibleForTesting
    public static final class SignatureParser {

        static String createSignature(String classifierId, String modelName, int hash) {
            return String.format(Locale.US, "%s|%s|%d", classifierId, modelName, hash);
        }

        static String getClassifierId(@Nullable String signature) {
            if (signature == null) {
                return "";
            }
            final int end = signature.indexOf("|");
            if (end >= 0) {
                return signature.substring(0, end);
            }
            return "";
        }

        static String getModelName(@Nullable String signature) {
            if (signature == null) {
                return "";
            }
            final int start = signature.indexOf("|") + 1;
            final int end = signature.indexOf("|", start);
            if (start >= 1 && end >= start) {
                return signature.substring(start, end);
            }
            return "";
        }

        static int getHash(@Nullable String signature) {
            if (signature == null) {
                return 0;
            }
            final int index1 = signature.indexOf("|");
            final int index2 = signature.indexOf("|", index1);
            if (index2 > 0) {
                return Integer.parseInt(signature.substring(index2));
            }
            return 0;
        }
    }
}
