import { matchPath } from 'react-router';
import uuid from 'uuid';
import { currentUser } from '../auth';
import { parseBrowserRepoURL } from '../repo';
import { repoRevRoute } from '../routes';
import { getPathExtension } from '../util';
import { browserExtensionMessageReceived, handleQueryEvents, pageViewQueryParameters } from './analyticsUtils';
import { serverAdmin } from './services/serverAdminWrapper';
import { telligent } from './services/telligentWrapper';
const uidKey = 'sourcegraphAnonymousUid';
class EventLogger {
    constructor() {
        this.hasStrippedQueryParameters = false;
        browserExtensionMessageReceived.subscribe(isInstalled => {
            telligent.setUserProperty('installed_chrome_extension', 'true');
            this.log('BrowserExtensionConnectedToServer');
            if (localStorage && localStorage.getItem('eventLogDebug') === 'true') {
                console.debug('%cBrowser extension detected, sync completed', 'color: #aaa');
            }
        });
        currentUser.subscribe(user => {
            this.user = user;
            if (user) {
                this.updateUser(user);
                this.log('UserProfileFetched');
            }
        }, error => {
            /* noop */
        });
    }
    /**
     * Set user-level properties in all external tracking services
     */
    updateUser(user) {
        this.setUserIds(user.sourcegraphID, user.username);
        if (user.email) {
            this.setUserEmail(user.email);
        }
    }
    /**
     * Set user ID in Telligent tracker script.
     * @param uniqueSourcegraphId Unique Sourcegraph user ID (corresponds to User.ID from backend)
     * @param username Human-readable user identifier, not guaranteed to always stay the same
     */
    setUserIds(uniqueSourcegraphId, username) {
        if (username) {
            telligent.setUserProperty('username', username);
        }
        if (uniqueSourcegraphId) {
            telligent.setUserProperty('user_id', uniqueSourcegraphId);
        }
    }
    setUserEmail(primaryEmail) {
        telligent.setUserProperty('email', primaryEmail);
    }
    /**
     * Log a pageview.
     * Page titles should be specific and human-readable in pascal case, e.g. "SearchResults" or "Blob" or "NewOrg"
     */
    logViewEvent(pageTitle, eventProperties, logUserEvent = true) {
        if (window.context.userAgentIsBot || !pageTitle) {
            return;
        }
        pageTitle = `View${pageTitle}`;
        const decoratedProps = Object.assign({}, this.decorateEventProperties(eventProperties), pageViewQueryParameters(window.location.href), { page_name: pageTitle, page_title: pageTitle });
        telligent.track('view', decoratedProps);
        if (logUserEvent) {
            serverAdmin.trackPageView();
        }
        this.logToConsole(pageTitle, decoratedProps);
        // Use flag to ensure URL query params are only stripped once
        if (!this.hasStrippedQueryParameters) {
            handleQueryEvents(window.location.href);
            this.hasStrippedQueryParameters = true;
        }
    }
    /**
     * Log a user action or event.
     * Event labels should be specific and follow a ${noun}${verb} structure in pascal case, e.g. "ButtonClicked" or "SignInInitiated"
     */
    log(eventLabel, eventProperties) {
        if (window.context.userAgentIsBot || !eventLabel) {
            return;
        }
        const decoratedProps = Object.assign({}, this.decorateEventProperties(eventProperties), { eventLabel });
        telligent.track(eventLabel, decoratedProps);
        serverAdmin.trackAction(eventLabel, decoratedProps);
        this.logToConsole(eventLabel, decoratedProps);
    }
    logToConsole(eventLabel, object) {
        if (localStorage && localStorage.getItem('eventLogDebug') === 'true') {
            console.debug('%cEVENT %s', 'color: #aaa', eventLabel, object);
        }
    }
    decorateEventProperties(eventProperties) {
        const props = Object.assign({}, eventProperties, { is_authed: this.user ? 'true' : 'false', path_name: window.location && window.location.pathname ? window.location.pathname.slice(1) : '' });
        const match = matchPath(window.location.pathname, {
            path: repoRevRoute.path,
            exact: repoRevRoute.exact,
        });
        if (match) {
            const u = parseBrowserRepoURL(window.location.href);
            props.repo = u.repoPath;
            props.rev = u.rev;
            if (u.filePath) {
                props.path = u.filePath;
                props.language = getPathExtension(u.filePath);
            }
        }
        return props;
    }
    /**
     * Access the Telligent unique user ID stored in a cookie on the user's computer. Cookie TTL is 2 years
     * https://sourcegraph.com/github.com/telligent-data/telligent-javascript-tracker@890d6a69b84fc0518a3e848f5469b34817da69fd/-/blob/src/js/tracker.js#L178
     *
     * Only used on Sourcegraph.com, not on self-hosted Sourcegraph instances.
     */
    getTelligentDuid() {
        return telligent.getTelligentDuid() || '';
    }
    /**
     * Generate a new anonymous user ID if one has not yet been set and stored.
     */
    generateAnonUserID() {
        const telID = this.getTelligentDuid();
        if (telID !== null) {
            return telID;
        }
        return uuid.v4();
    }
    /**
     * Get the anonymous identifier for this user (used to allow site admins
     * on a Sourcegraph instance to see a count of unique users on a daily,
     * weekly, and monthly basis).
     */
    getAnonUserID() {
        if (this.anonUid) {
            return this.anonUid;
        }
        let id = localStorage.getItem(uidKey);
        if (id === null) {
            id = this.generateAnonUserID();
            localStorage.setItem(uidKey, id);
        }
        this.anonUid = id;
        return this.anonUid;
    }
}
export const eventLogger = new EventLogger();
//# sourceMappingURL=eventLogger.js.map