<commit_before>package com.rehivetech.beeeon.util;

import com.rehivetech.beeeon.household.device.Module;
import com.rehivetech.beeeon.household.device.ModuleLog;
import com.rehivetech.beeeon.household.device.RefreshInterval;
import com.rehivetech.beeeon.household.device.values.BaseValue;
import com.rehivetech.beeeon.household.device.values.EnumValue;

import java.util.List;
import java.util.Random;

public class ValuesGenerator {
	private static final int RAW_ENUM_VALUES_COUNT_IN_LOG = 100;

	public static String generateValue(Module module, Random rand) {
		// For enum values simply choose some random value
		if (module.getValue() instanceof EnumValue) {
			EnumValue value = (EnumValue) module.getValue();
			List<EnumValue.Item> items = value.getEnumItems();
			EnumValue.Item item = items.get(rand.nextInt(items.size()));

			return item.getValue();
		}

		BaseValue value = module.getValue();
		BaseValue.Constraints constraints = value.getConstraints();

		double min = constraints != null && constraints.getMin() != null ? constraints.getMin() : value.getSaneMinimum();
		double max = constraints != null && constraints.getMax() != null ? constraints.getMax() : value.getSaneMaximum();
		double step = constraints != null && constraints.getGranularity() != null ? constraints.getGranularity() : value.getSaneStep();

		if (Double.isNaN(min) || Double.isNaN(max) || Double.isNaN(step)) {
			min = 0;
			max = 100;
			step = 1;
		}

		double lastValue = module.getValue().getDoubleValue();

		if (!module.getValue().hasValue() || Double.isNaN(lastValue)) {
			// Generate random first value
			Double next = (((int) (((max - min) / step) / 2) * step)) + min;
			return String.valueOf(next);
		}

		// Generate next value
		RefreshInterval refresh = module.getDevice().getRefresh();
		int changes = (refresh != null ? refresh.getIntervalIndex() + 1 : 1);
		double newValue = lastValue + (changes * step) * (rand.nextBoolean() ? 1 : -1);

		newValue = Math.max(min, Math.min(max, newValue));
		return (((int) newValue) == newValue ? String.valueOf((int) lastValue) : String.valueOf(lastValue));
	}

	public static ModuleLog generateLog(Module module, ModuleLog.DataPair pair, Random rand) {
		ModuleLog log = new ModuleLog(ModuleLog.DataType.AVERAGE, ModuleLog.DataInterval.RAW);

		long start = pair.interval.getStartMillis();
		long end = pair.interval.getEndMillis();

		BaseValue value = module.getValue();
		BaseValue.Constraints constraints = value.getConstraints();

		double min = constraints != null && constraints.getMin() != null ? constraints.getMin() : value.getSaneMinimum();
		double max = constraints != null && constraints.getMax() != null ? constraints.getMax() : value.getSaneMaximum();
		double step = constraints != null && constraints.getGranularity() != null ? constraints.getGranularity() : value.getSaneStep();

		if (Double.isNaN(min) || Double.isNaN(max) || Double.isNaN(step)) {
			min = 0;
			max = 100;
			step = 1;
		}

		double lastValue = pair.module.getValue().getDoubleValue();

		if (!module.getValue().hasValue() || Double.isNaN(lastValue)) {
			// Generate random first value
			lastValue = (((int) (((max - min) / step) / 2) * step)) + min;
		}

		boolean isEnum = (module.getValue() instanceof EnumValue);

		RefreshInterval refresh = module.getDevice().getRefresh();

		long everyMsecs;
		int changes = (refresh != null ? refresh.getIntervalIndex() + 1 : 1);

		if (isEnum || refresh == null) {
			// For enums we want fixed number of steps (because application surely wants raw values)
			// For devices without refresh it is the similar situation
			everyMsecs = (end - start) / RAW_ENUM_VALUES_COUNT_IN_LOG;
		} else {
			int refreshInterval = module.getDevice().getRefresh().getInterval();
			everyMsecs = Math.max(pair.gap.getSeconds(), refreshInterval) * 1000;
		}

		while (start < end) {
			// First make decision if we want any change
			if (rand.nextBoolean()) {
				if (isEnum) {
					List<EnumValue.Item> items = ((EnumValue) module.getValue()).getEnumItems();

					int pos = 0;
					for (EnumValue.Item item : items) {
						if (item.getId() == (int) lastValue) {
							break;
						}
						pos++;
					}
					// (size + pos + <-1,1>) % size  - first size is because it could end up to "-1"
					pos = (items.size() + pos + (rand.nextInt(3) - 1)) % items.size();
					lastValue = items.get(pos).getId();
				} else {
					lastValue = lastValue + (changes * step) * (rand.nextBoolean() ? 1 : -1);
				}

				lastValue = Math.max(min, Math.min(max, lastValue));
			}

			log.addValue(start, (float) lastValue);
			start += everyMsecs;
		}

		return log;<commit_msg>DemoData generating graph values for "time-based" axis<commit_after>package com.rehivetech.beeeon.util;

import android.util.Log;

import com.rehivetech.beeeon.household.device.Module;
import com.rehivetech.beeeon.household.device.ModuleLog;
import com.rehivetech.beeeon.household.device.RefreshInterval;
import com.rehivetech.beeeon.household.device.values.BaseValue;
import com.rehivetech.beeeon.household.device.values.EnumValue;

import java.util.List;
import java.util.Random;

public class ValuesGenerator {
	private static final String TAG = ValuesGenerator.class.getSimpleName();

	private static final int RAW_ENUM_VALUES_COUNT_IN_LOG = 100;

	public static String generateValue(Module module, Random rand) {
		// For enum values simply choose some random value
		if (module.getValue() instanceof EnumValue) {
			EnumValue value = (EnumValue) module.getValue();
			List<EnumValue.Item> items = value.getEnumItems();
			EnumValue.Item item = items.get(rand.nextInt(items.size()));

			return item.getValue();
		}

		BaseValue value = module.getValue();
		BaseValue.Constraints constraints = value.getConstraints();

		double min = constraints != null && constraints.getMin() != null ? constraints.getMin() : value.getSaneMinimum();
		double max = constraints != null && constraints.getMax() != null ? constraints.getMax() : value.getSaneMaximum();
		double step = constraints != null && constraints.getGranularity() != null ? constraints.getGranularity() : value.getSaneStep();

		if (Double.isNaN(min) || Double.isNaN(max) || Double.isNaN(step)) {
			min = 0;
			max = 100;
			step = 1;
		}

		double lastValue = module.getValue().getDoubleValue();

		if (!module.getValue().hasValue() || Double.isNaN(lastValue)) {
			// Generate random first value
			Double next = (((int) (((max - min) / step) / 2) * step)) + min;
			return String.valueOf(next);
		}

		// Generate next value
		RefreshInterval refresh = module.getDevice().getRefresh();
		int changes = (refresh != null ? refresh.getIntervalIndex() + 1 : 1);
		double newValue = lastValue + (changes * step) * (rand.nextBoolean() ? 1 : -1);

		newValue = Math.max(min, Math.min(max, newValue));
		return (((int) newValue) == newValue ? String.valueOf((int) lastValue) : String.valueOf(lastValue));
	}

	public static ModuleLog generateLog(Module module, ModuleLog.DataPair pair, Random rand) {
		ModuleLog log = new ModuleLog(ModuleLog.DataType.AVERAGE, ModuleLog.DataInterval.RAW);

		long start = pair.interval.getStartMillis();
		long end = pair.interval.getEndMillis();

		BaseValue value = module.getValue();
		BaseValue.Constraints constraints = value.getConstraints();

		double min = constraints != null && constraints.getMin() != null ? constraints.getMin() : value.getSaneMinimum();
		double max = constraints != null && constraints.getMax() != null ? constraints.getMax() : value.getSaneMaximum();
		double step = constraints != null && constraints.getGranularity() != null ? constraints.getGranularity() : value.getSaneStep();

		if (Double.isNaN(min) || Double.isNaN(max) || Double.isNaN(step)) {
			min = 0;
			max = 100;
			step = 1;
		}

		double lastValue = pair.module.getValue().getDoubleValue();

		if (!module.getValue().hasValue() || Double.isNaN(lastValue)) {
			// Generate random first value
			lastValue = (((int) (((max - min) / step) / 2) * step)) + min;
		}

		boolean isEnum = (module.getValue() instanceof EnumValue);

		RefreshInterval refresh = module.getDevice().getRefresh();

		// use refresh interval for raw data, or 1 second when has no refresh
		int refreshMsecs = (refresh != null ? refresh.getInterval() * 1000 : 1000);
		long everyMsecs = pair.gap == ModuleLog.DataInterval.RAW ? refreshMsecs : pair.gap.getSeconds() * 1000;

		// When wanting interval lower than refresh, we need to repeat same values to fill the refresh
		long skipCount = (refreshMsecs > everyMsecs ? refreshMsecs / everyMsecs : 1);

		int changes = (refresh != null ? refresh.getIntervalIndex() + 1 : 1);

		Log.d(TAG, String.format("Filling %d values", (end - start) / everyMsecs));

		while (start < end) {
			// First make decision if we want any change
			if (rand.nextBoolean()) {
				if (isEnum) {
					List<EnumValue.Item> items = ((EnumValue) module.getValue()).getEnumItems();

					int pos = 0;
					for (EnumValue.Item item : items) {
						if (item.getId() == (int) lastValue) {
							break;
						}
						pos++;
					}
					// (size + pos + <-1,1>) % size  - first size is because it could end up to "-1"
					pos = (items.size() + pos + (rand.nextInt(3) - 1)) % items.size();
					lastValue = items.get(pos).getId();
				} else {
					lastValue = lastValue + (changes * step) * (rand.nextBoolean() ? 1 : -1);
				}

				lastValue = Math.max(min, Math.min(max, lastValue));
			}

			for (long i=0; i<skipCount; i++) {
				log.addValue(start, (float) lastValue);
				start += everyMsecs;
			}
		}

		return log;
{'fraction_non_alphanumeric': 0.14425094418799833, 'fraction_numerical': 0.008078052874527905, 'mean_word_length': 3.8787103377686796, 'pattern_counts': {'":': 0, '<': 12, '<?xml version=': 0, '>': 10, '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': '2278287', 'n_tokens_mistral': 3365, 'n_tokens_neox': 2923, 'n_words': 746}