<commit_before>// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.internal.statistic.eventLog

import com.intellij.internal.statistic.eventLog.StatisticsEventEscaper.escapeFieldName
import com.intellij.internal.statistic.utils.PluginInfo
import com.intellij.internal.statistic.utils.StatisticsUtil
import com.intellij.internal.statistic.utils.addPluginInfoTo
import com.intellij.internal.statistic.utils.getPluginInfo
import com.intellij.lang.Language
import com.intellij.openapi.actionSystem.ActionPlaces
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.SystemInfo
import com.intellij.openapi.util.Version
import com.intellij.openapi.util.text.StringUtil
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.annotations.NonNls
import java.awt.event.InputEvent
import java.awt.event.KeyEvent
import java.awt.event.MouseEvent
import java.util.*

private val LOG = logger<FeatureUsageData>()

/**
 * <p>FeatureUsageData represents additional data for reported event.</p>
 *
 * <h3>Example</h3>
 *
 * <p>My usage collector collects actions invocations. <i>"my.foo.action"</i> could be invoked from one of the following contexts:
 * "main.menu", "context.menu", "my.dialog", "all-actions-run".</p>
 *
 * <p>If I write {@code FUCounterUsageLogger.logEvent("my.foo.action", "bar")}, I'll know how many times the action "bar" was invoked (e.g. 239)</p>
 *
 * <p>If I write {@code FUCounterUsageLogger.logEvent("my.foo.action", "bar", new FeatureUsageData().addPlace(place))}, I'll get the same
 * total count of action invocations (239), but I'll also know that the action was called 3 times from "main.menu", 235 times from "my.dialog" and only once from "context.menu".
 * <br/>
 * </p>
 */
@ApiStatus.Internal
class FeatureUsageData {
  private var data: MutableMap<String, Any> = HashMap()

  companion object {
    // don't list "version" as "platformDataKeys" because it format depends a lot on the tool
    val platformDataKeys: List<String> = listOf("plugin", "project", "os", "plugin_type", "lang", "current_file", "input_event", "place",
                                                "file_path", "anonymous_id")
  }

  /**
   * Project data is added automatically for project state collectors and project-wide counter events.
   *
   * @see com.intellij.internal.statistic.service.fus.collectors.ProjectUsagesCollector
   * @see com.intellij.internal.statistic.service.fus.collectors.FUCounterUsageLogger.logEvent(Project, String, String)
   * @see com.intellij.internal.statistic.service.fus.collectors.FUCounterUsageLogger.logEvent(Project, String, String, FeatureUsageData)
   */
  fun addProject(project: Project?): FeatureUsageData {
    if (project != null) {
      data["project"] = StatisticsUtil.getProjectId(project)
    }
    return this<commit_msg>IDEA-CR-63733 FUS: record anonymized client id in event data if it's not default (IDEA-243603)<commit_after>// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.internal.statistic.eventLog

import com.intellij.codeWithMe.ClientId
import com.intellij.internal.statistic.eventLog.StatisticsEventEscaper.escapeFieldName
import com.intellij.internal.statistic.utils.PluginInfo
import com.intellij.internal.statistic.utils.StatisticsUtil
import com.intellij.internal.statistic.utils.addPluginInfoTo
import com.intellij.internal.statistic.utils.getPluginInfo
import com.intellij.lang.Language
import com.intellij.openapi.actionSystem.ActionPlaces
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.SystemInfo
import com.intellij.openapi.util.Version
import com.intellij.openapi.util.text.StringUtil
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.annotations.NonNls
import java.awt.event.InputEvent
import java.awt.event.KeyEvent
import java.awt.event.MouseEvent
import java.util.*

private val LOG = logger<FeatureUsageData>()

/**
 * <p>FeatureUsageData represents additional data for reported event.</p>
 *
 * <h3>Example</h3>
 *
 * <p>My usage collector collects actions invocations. <i>"my.foo.action"</i> could be invoked from one of the following contexts:
 * "main.menu", "context.menu", "my.dialog", "all-actions-run".</p>
 *
 * <p>If I write {@code FUCounterUsageLogger.logEvent("my.foo.action", "bar")}, I'll know how many times the action "bar" was invoked (e.g. 239)</p>
 *
 * <p>If I write {@code FUCounterUsageLogger.logEvent("my.foo.action", "bar", new FeatureUsageData().addPlace(place))}, I'll get the same
 * total count of action invocations (239), but I'll also know that the action was called 3 times from "main.menu", 235 times from "my.dialog" and only once from "context.menu".
 * <br/>
 * </p>
 */
@ApiStatus.Internal
class FeatureUsageData {
  private var data: MutableMap<String, Any> = HashMap()

  init {
    val clientId = ClientId.currentOrNull
    if (clientId != null && clientId != ClientId.defaultLocalId) {
      addClientId(clientId.value)
    }
  }

  companion object {
    // don't list "version" as "platformDataKeys" because it format depends a lot on the tool
    val platformDataKeys: List<String> = listOf("plugin", "project", "os", "plugin_type", "lang", "current_file", "input_event", "place",
                                                "file_path", "anonymous_id", "client_id")
  }

  fun addClientId(clientId: String?): FeatureUsageData {
    clientId?.let {
      val permanentClientId = parsePermanentClientId(clientId)
      data["client_id"] = EventLogConfiguration.anonymize(permanentClientId)
    }
    return this
  }

  private fun parsePermanentClientId(clientId: String): String {
    val separator = clientId.indexOf('-')
    if (separator > 0) {
      return clientId.substring(0, separator)
    }
    return clientId
  }

  /**
   * Project data is added automatically for project state collectors and project-wide counter events.
   *
   * @see com.intellij.internal.statistic.service.fus.collectors.ProjectUsagesCollector
   * @see com.intellij.internal.statistic.service.fus.collectors.FUCounterUsageLogger.logEvent(Project, String, String)
   * @see com.intellij.internal.statistic.service.fus.collectors.FUCounterUsageLogger.logEvent(Project, String, String, FeatureUsageData)
   */
  fun addProject(project: Project?): FeatureUsageData {
    if (project != null) {
      data["project"] = StatisticsUtil.getProjectId(project)
    }
    return this
{'fraction_non_alphanumeric': 0.11315560707041437, 'fraction_numerical': 0.00825847580411475, 'mean_word_length': 4.53125, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 36, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2019663', 'n_tokens_mistral': 2156, 'n_tokens_neox': 2073, 'n_words': 517}