<commit_before>package com.tapstream.sdk;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.TimeZone;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

class Core {
	public static final String VERSION = "2.8.1";
	private static final String EVENT_URL_TEMPLATE = "https://api.tapstream.com/%s/event/%s/";
	private static final String HIT_URL_TEMPLATE = "http://api.tapstream.com/%s/hit/%s.gif";
	private static final String CONVERSION_URL_TEMPLATE = "https://reporting.tapstream.com/v1/timelines/lookup?secret=%s&event_session=%s";
	private static final int MAX_THREADS = 1;
	private static final int CONVERSION_POLL_INTERVAL = 1;
	private static final int CONVERSION_POLL_COUNT = 10;
	private static final int EVENT_RETENTION_TIME = 3;

	private Delegate delegate;
	private Platform platform;
	private CoreListener listener;
	private ActivityEventSource activityEventSource;
	private Runnable adIdFetcher;
	private Config config;
	private String accountName;
	private String secret;
	private String appName;
	private ScheduledThreadPoolExecutor executor;
	private StringBuilder postData = null;
	private Set<String> firingEvents = new HashSet<String>(16);
	private Set<String> firedEvents = new HashSet<String>(16);
	private String failingEventId = null;
	private int delay = 0;
	private boolean retainEvents = true;
	private List<Event> retainedEvents = new ArrayList<Event>();

	Core(Delegate delegate, Platform platform, CoreListener listener, ActivityEventSource activityEventSource, Runnable adIdFetcher, String accountName, String developerSecret, Config config) {
		this.delegate = delegate;
		this.platform = platform;
		this.listener = listener;
		this.activityEventSource = activityEventSource;
		this.adIdFetcher = adIdFetcher;
		this.config = config;

		this.accountName = clean(accountName);
		this.secret = developerSecret;
		makePostArgs();

		firedEvents = platform.loadFiredEvents();

		executor = new ScheduledThreadPoolExecutor(MAX_THREADS, platform.makeWorkerThreadFactory());
		executor.prestartAllCoreThreads();
	}

	public void start() {
		// Automatically fire run event
		appName = platform.getAppName();
		if(appName == null) {
			appName = "";
		}
		final String appNameFinal = appName;

		if(config.getFireAutomaticInstallEvent()) {
			String installEventName = config.getInstallEventName();
			if(installEventName != null) {
				fireEvent(new Event(installEventName, true));
			} else {
				fireEvent(new Event(String.format(Locale.US, "android-%s-install", appName), true));
			}
		}

		if(config.getFireAutomaticOpenEvent()) {
			String openEventName = config.getOpenEventName();
			if(openEventName != null) {
				fireEvent(new Event(openEventName, false));
			} else {
				fireEvent(new Event(String.format(Locale.US, "android-%s-open", appName), false));
			}
		}

		activityEventSource.setListener(new ActivityEventSource.ActivityListener() {
			@Override
			public void onOpen() {
				if(config.getFireAutomaticOpenEvent()) {
					String openEventName = config.getOpenEventName();
					if(openEventName != null) {
						fireEvent(new Event(openEventName, false));
					} else {
						fireEvent(new Event(String.format(Locale.US, "android-%s-open", appNameFinal), false));
					}
				}
			}
		});

		// If google play services is available, we'll have an AndroidAdvertisingId instance.
		// If we do, then schedule it immediately so it can fetch the ID.
		if(adIdFetcher != null && config.getCollectAdvertisingId()) {
			executor.schedule(adIdFetcher, 0, TimeUnit.SECONDS);
		}

		// Flush retained events (and disable retention) after a short delay
		final Core self = this;
		executor.schedule(new Runnable() {
			@Override
			public void run() {
				synchronized(self) {
					retainEvents = false;

					// Add referrer info to our common post data
					String referrer = platform.getReferrer();
					if(referrer != null && referrer.length() > 0) {
						appendPostPair("", "android-referrer", referrer);
					}

					// Add android advertising id to our common post data
					if(self.config.getCollectAdvertisingId()) {
						String aaid = platform.getAdvertisingId();
						if(aaid != null && aaid.length() > 0) {
							appendPostPair("", "android-advertising-id", aaid);
						}else{
							Logging.log(Logging.WARN, "Advertising id could be collected. Is Google Play Services installed?");
						}
						Boolean limitAdTracking = platform.getLimitAdTracking();
						if(limitAdTracking != null) {
							appendPostPair("", "android-limit-ad-tracking", limitAdTracking);
						}
					}
				}
				for(Event e: retainedEvents) {
					fireEvent(e);
				}
				retainedEvents = null;
			}
		}, EVENT_RETENTION_TIME, TimeUnit.SECONDS);
	}

	public synchronized void fireEvent(final Event e) {
		// If we are retaining events, add them to a list to be sent later
		if(retainEvents) {
			retainedEvents.add(e);
			return;
		}

		// Transaction events need their names prefixed with platform and app name
		if(e.isTransaction()) {
			e.setNamePrefix(appName);
		}

		// Add global event params if they have not yet been added<commit_msg>Fix tag<commit_after>package com.tapstream.sdk;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.TimeZone;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

class Core {
	public static final String VERSION = "2.8.1";
	private static final String EVENT_URL_TEMPLATE = "https://api.tapstream.com/%s/event/%s/";
	private static final String HIT_URL_TEMPLATE = "http://api.tapstream.com/%s/hit/%s.gif";
	private static final String CONVERSION_URL_TEMPLATE = "https://reporting.tapstream.com/v1/timelines/lookup?secret=%s&event_session=%s";
	private static final int MAX_THREADS = 1;
	private static final int CONVERSION_POLL_INTERVAL = 1;
	private static final int CONVERSION_POLL_COUNT = 10;
	private static final int EVENT_RETENTION_TIME = 3;

	private Delegate delegate;
	private Platform platform;
	private CoreListener listener;
	private ActivityEventSource activityEventSource;
	private Runnable adIdFetcher;
	private Config config;
	private String accountName;
	private String secret;
	private String appName;
	private ScheduledThreadPoolExecutor executor;
	private StringBuilder postData = null;
	private Set<String> firingEvents = new HashSet<String>(16);
	private Set<String> firedEvents = new HashSet<String>(16);
	private String failingEventId = null;
	private int delay = 0;
	private boolean retainEvents = true;
	private List<Event> retainedEvents = new ArrayList<Event>();

	Core(Delegate delegate, Platform platform, CoreListener listener, ActivityEventSource activityEventSource, Runnable adIdFetcher, String accountName, String developerSecret, Config config) {
		this.delegate = delegate;
		this.platform = platform;
		this.listener = listener;
		this.activityEventSource = activityEventSource;
		this.adIdFetcher = adIdFetcher;
		this.config = config;

		this.accountName = clean(accountName);
		this.secret = <PASSWORD>Secret;
		makePostArgs();

		firedEvents = platform.loadFiredEvents();

		executor = new ScheduledThreadPoolExecutor(MAX_THREADS, platform.makeWorkerThreadFactory());
		executor.prestartAllCoreThreads();
	}

	public void start() {
		// Automatically fire run event
		appName = platform.getAppName();
		if(appName == null) {
			appName = "";
		}
		final String appNameFinal = appName;

		if(config.getFireAutomaticInstallEvent()) {
			String installEventName = config.getInstallEventName();
			if(installEventName != null) {
				fireEvent(new Event(installEventName, true));
			} else {
				fireEvent(new Event(String.format(Locale.US, "android-%s-install", appName), true));
			}
		}

		if(config.getFireAutomaticOpenEvent()) {
			String openEventName = config.getOpenEventName();
			if(openEventName != null) {
				fireEvent(new Event(openEventName, false));
			} else {
				fireEvent(new Event(String.format(Locale.US, "android-%s-open", appName), false));
			}
		}

		activityEventSource.setListener(new ActivityEventSource.ActivityListener() {
			@Override
			public void onOpen() {
				if(config.getFireAutomaticOpenEvent()) {
					String openEventName = config.getOpenEventName();
					if(openEventName != null) {
						fireEvent(new Event(openEventName, false));
					} else {
						fireEvent(new Event(String.format(Locale.US, "android-%s-open", appNameFinal), false));
					}
				}
			}
		});

		// If google play services is available, we'll have an AndroidAdvertisingId instance.
		// If we do, then schedule it immediately so it can fetch the ID.
		if(adIdFetcher != null && config.getCollectAdvertisingId()) {
			executor.schedule(adIdFetcher, 0, TimeUnit.SECONDS);
		}

		// Flush retained events (and disable retention) after a short delay
		final Core self = this;
		executor.schedule(new Runnable() {
			@Override
			public void run() {
				synchronized(self) {
					retainEvents = false;

					// Add referrer info to our common post data
					String referrer = platform.getReferrer();
					if(referrer != null && referrer.length() > 0) {
						appendPostPair("", "android-referrer", referrer);
					}

					// Add android advertising id to our common post data
					if(self.config.getCollectAdvertisingId()) {
						String aaid = platform.getAdvertisingId();
						if(aaid != null && aaid.length() > 0) {
							appendPostPair("", "hardware-android-advertising-id", aaid);
						}else{
							Logging.log(Logging.WARN, "Advertising id could be collected. Is Google Play Services installed?");
						}
						Boolean limitAdTracking = platform.getLimitAdTracking();
						if(limitAdTracking != null) {
							appendPostPair("", "android-limit-ad-tracking", limitAdTracking);
						}
					}
				}
				for(Event e: retainedEvents) {
					fireEvent(e);
				}
				retainedEvents = null;
			}
		}, EVENT_RETENTION_TIME, TimeUnit.SECONDS);
	}

	public synchronized void fireEvent(final Event e) {
		// If we are retaining events, add them to a list to be sent later
		if(retainEvents) {
			retainedEvents.add(e);
			return;
		}

		// Transaction events need their names prefixed with platform and app name
		if(e.isTransaction()) {
			e.setNamePrefix(appName);
		}

		// Add global event params if they have not yet been added
{'fraction_non_alphanumeric': 0.10716945996275605, 'fraction_numerical': 0.003165735567970205, 'mean_word_length': 4.221682061254254, 'pattern_counts': {'":': 0, '<': 16, '<?xml version=': 0, '>': 20, 'https://': 4, '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': '4428511', 'n_tokens_mistral': 3722, 'n_tokens_neox': 3191, 'n_words': 824}