<commit_before>package com.intellij.stats.completion.experiment

import com.google.gson.Gson
import com.intellij.openapi.application.ApplicationManager
import com.intellij.stats.completion.RequestService
import com.intellij.stats.completion.UrlProvider
import com.intellij.util.Time
import java.util.*

class ABTesterHelper(private val requestSender: RequestService, private val urlProvider: UrlProvider) {
    private val gson = Gson()

    @Volatile private var lastUpdate = Date(0)
    @Volatile private var experimentInfo = ExperimentInfo()

    fun isPerformExperiment(): Boolean {
        if (isOutdated(lastUpdate)) {
            onPooledThread { updateExperimentData() }
        }
        return experimentInfo.performExperiment
    }

    fun getExperimentVersion(): Int {
        if (isOutdated(lastUpdate)) {
            onPooledThread { updateExperimentData() }
        }
        return experimentInfo.experimentVersion
    }
    
    private fun onPooledThread(block: () -> Unit) {
        val app = ApplicationManager.getApplication()
        if (app.isUnitTestMode) block() else app.executeOnPooledThread { block() }
    }
    
    protected fun updateExperimentData() {
        val response = requestSender.get(urlProvider.experimentDataUrl)
        if (response != null && response.isOK()) {
            experimentInfo = gson.fromJson(response.text, ExperimentInfo::class.java)
            lastUpdate = Date()
        }
    }

    private fun isOutdated(lastUpdate: Date): Boolean {
        return lastUpdate.time < System.currentTimeMillis() - 30 * Time.MINUTE
    }
}

class ExperimentInfo(var performExperiment: Boolean, var experimentVersion: Int) {
    constructor() : this(false, 0)
}<commit_msg>Persist experimental info and last update date in PropertiesComponent<commit_after>package com.intellij.stats.completion.experiment

import com.google.gson.Gson
import com.intellij.ide.util.PropertiesComponent
import com.intellij.openapi.application.ApplicationManager
import com.intellij.stats.completion.RequestService
import com.intellij.stats.completion.UrlProvider
import com.intellij.util.Time
import java.util.*

class ABTesterHelper(private val requestSender: RequestService, private val urlProvider: UrlProvider) {
    private val gson = Gson()

    @Volatile private var lastUpdate = loadLastUpdated()
    @Volatile private var experimentInfo = loadInfo()

    fun isPerformExperiment(): Boolean {
        if (isOutdated(lastUpdate)) {
            onPooledThread { updateExperimentData() }
        }
        return experimentInfo.performExperiment
    }

    fun getExperimentVersion(): Int {
        if (isOutdated(lastUpdate)) {
            onPooledThread { updateExperimentData() }
        }
        return experimentInfo.experimentVersion
    }
    
    private fun onPooledThread(block: () -> Unit) {
        val app = ApplicationManager.getApplication()
        if (app.isUnitTestMode) block() else app.executeOnPooledThread { block() }
    }
    
    protected fun updateExperimentData() {
        val response = requestSender.get(urlProvider.experimentDataUrl)
        if (response != null && response.isOK()) {
            experimentInfo = gson.fromJson(response.text, ExperimentInfo::class.java)
            lastUpdate = Date()
            saveInfo(experimentInfo)
            saveLastUpdated(lastUpdate)
        }
    }

    private fun isOutdated(lastUpdate: Date): Boolean {
        return lastUpdate.time < System.currentTimeMillis() - 30 * Time.MINUTE
    }

    private fun loadInfo(): ExperimentInfo {
        val component = PropertiesComponent.getInstance()
        val isPerformExperiment = component.getBoolean("completion.stats.collector.perform.experiment", false)
        val experimentVersion = component.getInt("completion.stats.collector.perform.experiment.version", 0)
        return ExperimentInfo(isPerformExperiment, experimentVersion)
    }

    private fun saveInfo(info: ExperimentInfo) {
        val component = PropertiesComponent.getInstance()
        component.setValue("completion.stats.collector.perform.experiment", info.performExperiment)
        component.setValue("completion.stats.collector.perform.experiment.version", info.experimentVersion.toString())
    }
    
    private fun saveLastUpdated(date: Date) {
        val component = PropertiesComponent.getInstance()
        component.setValue("completion.stats.collector.perform.last.update", date.time.toString())
    }

    private fun loadLastUpdated(): Date {
        val component = PropertiesComponent.getInstance()
        val time = component.getOrInitLong("completion.stats.collector.perform.last.update", 0)
        return Date(time)
    }
    
}

data class ExperimentInfo(var performExperiment: Boolean, var experimentVersion: Int) {
    constructor() : this(false, 0)
}
{'fraction_non_alphanumeric': 0.09251559251559252, 'fraction_numerical': 0.0018711018711018712, 'mean_word_length': 3.4056776556776556, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4631489', 'n_tokens_mistral': 1299, 'n_tokens_neox': 1266, 'n_words': 270}