// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.chromium.android_webview;

import android.content.Context;

import org.chromium.autofill.mojom.SubmissionSource;
import org.chromium.base.metrics.RecordHistogram;

import java.util.concurrent.TimeUnit;

/**
 * The class for WebView autofill UMA.
 */
public class AwAutofillUMA {
    // Records whether the Autofill service is enabled or not.
    public static final String UMA_AUTOFILL_WEBVIEW_ENABLED = "Autofill.WebView.Enabled";

    // Records whether the Autofill provider is created by activity context or not.
    public static final String UMA_AUTOFILL_WEBVIEW_CREATED_BY_ACTIVITY_CONTEXT =
            "Autofill.WebView.CreatedByActivityContext";

    // Records what happened in an autofill session.
    public static final String UMA_AUTOFILL_WEBVIEW_AUTOFILL_SESSION =
            "Autofill.WebView.AutofillSession";
    // The possible value of UMA_AUTOFILL_WEBVIEW_AUTOFILL_SESSION.
    public static final int SESSION_UNKNOWN = 0;
    public static final int NO_CALLBACK_FORM_FRAMEWORK = 1;
    public static final int NO_SUGGESTION_USER_CHANGE_FORM_FORM_SUBMITTED = 2;
    public static final int NO_SUGGESTION_USER_CHANGE_FORM_NO_FORM_SUBMITTED = 3;
    public static final int NO_SUGGESTION_USER_NOT_CHANGE_FORM_FORM_SUBMITTED = 4;
    public static final int NO_SUGGESTION_USER_NOT_CHANGE_FORM_NO_FORM_SUBMITTED = 5;
    public static final int USER_SELECT_SUGGESTION_USER_CHANGE_FORM_FORM_SUBMITTED = 6;
    public static final int USER_SELECT_SUGGESTION_USER_CHANGE_FORM_NO_FORM_SUBMITTED = 7;
    public static final int USER_SELECT_SUGGESTION_USER_NOT_CHANGE_FORM_FORM_SUBMITTED = 8;
    public static final int USER_SELECT_SUGGESTION_USER_NOT_CHANGE_FORM_NO_FORM_SUBMITTED = 9;
    public static final int USER_NOT_SELECT_SUGGESTION_USER_CHANGE_FORM_FORM_SUBMITTED = 10;
    public static final int USER_NOT_SELECT_SUGGESTION_USER_CHANGE_FORM_NO_FORM_SUBMITTED = 11;
    public static final int USER_NOT_SELECT_SUGGESTION_USER_NOT_CHANGE_FORM_FORM_SUBMITTED = 12;
    public static final int USER_NOT_SELECT_SUGGESTION_USER_NOT_CHANGE_FORM_NO_FORM_SUBMITTED = 13;
    public static final int AUTOFILL_SESSION_HISTOGRAM_COUNT = 14;

    // Records whether user changed autofilled field if user ever changed the form. The action isn't
    // recorded if user didn't change form at all.
    public static final String UMA_AUTOFILL_USER_CHANGED_AUTOFILLED_FIELD =
            "Autofill.WebView.UserChangedAutofilledField";

    public static final String UMA_AUTOFILL_WEBVIEW_SUBMISSION_SOURCE =
            "Autofill.WebView.SubmissionSource";
    // The possible value of UMA_AUTOFILL_WEBVIEW_SUBMISSION_SOURCE.
    public static final int SAME_DOCUMENT_NAVIGATION = 0;
    public static final int XHR_SUCCEEDED = 1;
    public static final int FRAME_DETACHED = 2;
    public static final int DOM_MUTATION_AFTER_XHR = 3;
    public static final int PROBABLY_FORM_SUBMITTED = 4;
    public static final int FORM_SUBMISSION = 5;
    public static final int SUBMISSION_SOURCE_HISTOGRAM_COUNT = 6;

    // The million seconds from user touched the field to WebView started autofill session.
    public static final String UMA_AUTOFILL_WEBVIEW_TRIGGERING_TIME =
            "Autofill.WebView.TriggeringTime";

    // The million seconds from WebView started autofill session to suggestion was displayed.
    public static final String UMA_AUTOFILL_WEBVIEW_SUGGESTION_TIME =
            "Autofill.WebView.SuggestionTime";

    // The expected time range of time is from 10ms to 2 seconds, and 50 buckets is sufficient.
    private static final long MIN_TIME_MILLIS = 10;
    private static final long MAX_TIME_MILLIS = TimeUnit.SECONDS.toMillis(2);
    private static final int NUM_OF_BUCKETS = 50;

    private static void recordTimesHistogram(String name, long durationMillis) {
        RecordHistogram.recordCustomTimesHistogram(
                name, durationMillis, MIN_TIME_MILLIS, MAX_TIME_MILLIS, NUM_OF_BUCKETS);
    }

    private static class SessionRecorder {
        public static final int EVENT_VIRTUAL_STRUCTURE_PROVIDED = 0x1 << 0;
        public static final int EVENT_SUGGESTION_DISPLAYED = 0x1 << 1;
        public static final int EVENT_FORM_AUTOFILLED = 0x1 << 2;
        public static final int EVENT_USER_CHANGED_FIELD_VALUE = 0x1 << 3;
        public static final int EVENT_FORM_SUBMITTED = 0x1 << 4;
        public static final int EVENT_USER_CHANGED_AUTOFILLED_FIELD = 0x1 << 5;

        private Long mSuggestionTimeMillis;

        public void record(int event) {
            // Not record any event until we get EVENT_VIRTUAL_STRUCTURE_PROVIDED which makes the
            // following events meaningful.
            if (event != EVENT_VIRTUAL_STRUCTURE_PROVIDED && mState == 0) return;
            if (EVENT_USER_CHANGED_FIELD_VALUE == event && mUserChangedAutofilledField == null) {
                mUserChangedAutofilledField = Boolean.valueOf(false);
            } else if (EVENT_USER_CHANGED_AUTOFILLED_FIELD == event) {
                if (mUserChangedAutofilledField == null) {
                    mUserChangedAutofilledField = Boolean.valueOf(true);
                }
                mUserChangedAutofilledField = true;
                event = EVENT_USER_CHANGED_FIELD_VALUE;
            }
            mState |= event;
        }

        public void setSuggestionTimeMillis(long suggestionTimeMillis) {
            // Only record first suggestion.
            if (mSuggestionTimeMillis == null) {
                mSuggestionTimeMillis = Long.valueOf(suggestionTimeMillis);
            }
        }

        public void recordHistogram() {
            RecordHistogram.recordEnumeratedHistogram(UMA_AUTOFILL_WEBVIEW_AUTOFILL_SESSION,
                    toUMAAutofillSessionValue(), AUTOFILL_SESSION_HISTOGRAM_COUNT);
            // Only record if user ever changed form.
            if (mUserChangedAutofilledField != null) {
                RecordHistogram.recordBooleanHistogram(
                        UMA_AUTOFILL_USER_CHANGED_AUTOFILLED_FIELD, mUserChangedAutofilledField);
            }
            if (mSuggestionTimeMillis != null) {
                recordTimesHistogram(UMA_AUTOFILL_WEBVIEW_SUGGESTION_TIME, mSuggestionTimeMillis);
            }
        }

        private int toUMAAutofillSessionValue() {
            if (mState == 0)
                return NO_CALLBACK_FORM_FRAMEWORK;
            else if (mState == EVENT_VIRTUAL_STRUCTURE_PROVIDED)
                return NO_SUGGESTION_USER_NOT_CHANGE_FORM_NO_FORM_SUBMITTED;
            else if (mState == (EVENT_VIRTUAL_STRUCTURE_PROVIDED | EVENT_USER_CHANGED_FIELD_VALUE))
                return NO_SUGGESTION_USER_CHANGE_FORM_NO_FORM_SUBMITTED;
            else if (mState == (EVENT_VIRTUAL_STRUCTURE_PROVIDED | EVENT_FORM_SUBMITTED))
                return NO_SUGGESTION_USER_NOT_CHANGE_FORM_FORM_SUBMITTED;
            else if (mState
                    == (EVENT_VIRTUAL_STRUCTURE_PROVIDED | EVENT_USER_CHANGED_FIELD_VALUE
                               | EVENT_FORM_SUBMITTED))
                return NO_SUGGESTION_USER_CHANGE_FORM_FORM_SUBMITTED;
            else if (mState
                    == (EVENT_VIRTUAL_STRUCTURE_PROVIDED | EVENT_SUGGESTION_DISPLAYED
                               | EVENT_FORM_AUTOFILLED))
                return USER_SELECT_SUGGESTION_USER_NOT_CHANGE_FORM_NO_FORM_SUBMITTED;
            else if (mState
                    == (EVENT_VIRTUAL_STRUCTURE_PROVIDED | EVENT_SUGGESTION_DISPLAYED
                               | EVENT_FORM_AUTOFILLED | EVENT_FORM_SUBMITTED))
                return USER_SELECT_SUGGESTION_USER_NOT_CHANGE_FORM_FORM_SUBMITTED;
            else if (mState
                    == (EVENT_VIRTUAL_STRUCTURE_PROVIDED | EVENT_SUGGESTION_DISPLAYED
                               | EVENT_FORM_AUTOFILLED | EVENT_USER_CHANGED_FIELD_VALUE
                               | EVENT_FORM_SUBMITTED))
                return USER_SELECT_SUGGESTION_USER_CHANGE_FORM_FORM_SUBMITTED;
            else if (mState
                    == (EVENT_VIRTUAL_STRUCTURE_PROVIDED | EVENT_SUGGESTION_DISPLAYED
                               | EVENT_FORM_AUTOFILLED | EVENT_USER_CHANGED_FIELD_VALUE))
                return USER_SELECT_SUGGESTION_USER_CHANGE_FORM_NO_FORM_SUBMITTED;
            else if (mState == (EVENT_VIRTUAL_STRUCTURE_PROVIDED | EVENT_SUGGESTION_DISPLAYED))
                return USER_NOT_SELECT_SUGGESTION_USER_NOT_CHANGE_FORM_NO_FORM_SUBMITTED;
            else if (mState
                    == (EVENT_VIRTUAL_STRUCTURE_PROVIDED | EVENT_SUGGESTION_DISPLAYED
                               | EVENT_FORM_SUBMITTED))
                return USER_NOT_SELECT_SUGGESTION_USER_NOT_CHANGE_FORM_FORM_SUBMITTED;
            else if (mState
                    == (EVENT_VIRTUAL_STRUCTURE_PROVIDED | EVENT_SUGGESTION_DISPLAYED
                               | EVENT_USER_CHANGED_FIELD_VALUE | EVENT_FORM_SUBMITTED))
                return USER_NOT_SELECT_SUGGESTION_USER_CHANGE_FORM_FORM_SUBMITTED;
            else if (mState
                    == (EVENT_VIRTUAL_STRUCTURE_PROVIDED | EVENT_SUGGESTION_DISPLAYED
                               | EVENT_USER_CHANGED_FIELD_VALUE))
                return USER_NOT_SELECT_SUGGESTION_USER_CHANGE_FORM_NO_FORM_SUBMITTED;
            else
                return SESSION_UNKNOWN;
        }

        private int mState;
        private Boolean mUserChangedAutofilledField;
    }

    private SessionRecorder mRecorder;
    private Boolean mAutofillDisabled;

    public AwAutofillUMA(Context context) {
        RecordHistogram.recordBooleanHistogram(UMA_AUTOFILL_WEBVIEW_CREATED_BY_ACTIVITY_CONTEXT,
                AwContents.activityFromContext(context) != null);
    }

    public void onFormSubmitted(int submissionSource) {
        if (mRecorder != null) mRecorder.record(SessionRecorder.EVENT_FORM_SUBMITTED);
        recordSession();
        // We record this no matter autofill service is disabled or not.
        RecordHistogram.recordEnumeratedHistogram(UMA_AUTOFILL_WEBVIEW_SUBMISSION_SOURCE,
                toUMASubmissionSource(submissionSource), SUBMISSION_SOURCE_HISTOGRAM_COUNT);
    }

    public void onSessionStarted(boolean autofillDisabled) {
        // Record autofill status once per instance and only if user triggers the autofill.
        if (mAutofillDisabled == null || mAutofillDisabled.booleanValue() != autofillDisabled) {
            RecordHistogram.recordBooleanHistogram(UMA_AUTOFILL_WEBVIEW_ENABLED, !autofillDisabled);
            mAutofillDisabled = Boolean.valueOf(autofillDisabled);
        }

        if (mRecorder != null) recordSession();
        mRecorder = new SessionRecorder();
    }

    public void onVirtualStructureProvided() {
        if (mRecorder != null) mRecorder.record(SessionRecorder.EVENT_VIRTUAL_STRUCTURE_PROVIDED);
    }

    public void onSuggestionDisplayed(long suggestionTimeMillis) {
        if (mRecorder != null) {
            mRecorder.record(SessionRecorder.EVENT_SUGGESTION_DISPLAYED);
            mRecorder.setSuggestionTimeMillis(suggestionTimeMillis);
        }
    }

    public void onAutofill() {
        if (mRecorder != null) mRecorder.record(SessionRecorder.EVENT_FORM_AUTOFILLED);
    }

    public void onUserChangeFieldValue(boolean isPreviouslyAutofilled) {
        if (mRecorder == null) return;
        if (isPreviouslyAutofilled)
            mRecorder.record(SessionRecorder.EVENT_USER_CHANGED_AUTOFILLED_FIELD);
        else
            mRecorder.record(SessionRecorder.EVENT_USER_CHANGED_FIELD_VALUE);
    }

    private void recordSession() {
        if (mAutofillDisabled != null && !mAutofillDisabled.booleanValue() && mRecorder != null) {
            mRecorder.recordHistogram();
        }
        mRecorder = null;
    }

    private int toUMASubmissionSource(int source) {
        switch (source) {
            case SubmissionSource.SAME_DOCUMENT_NAVIGATION:
                return SAME_DOCUMENT_NAVIGATION;
            case SubmissionSource.XHR_SUCCEEDED:
                return XHR_SUCCEEDED;
            case SubmissionSource.FRAME_DETACHED:
                return FRAME_DETACHED;
            case SubmissionSource.DOM_MUTATION_AFTER_XHR:
                return DOM_MUTATION_AFTER_XHR;
            case SubmissionSource.PROBABLY_FORM_SUBMITTED:
                return PROBABLY_FORM_SUBMITTED;
            case SubmissionSource.FORM_SUBMISSION:
                return FORM_SUBMISSION;
            default:
                return SUBMISSION_SOURCE_HISTOGRAM_COUNT;
        }
    }
}
