/**
 * Typesafe wrapper for wsi4.sharedData
 */

import {
	AutomaticProcessConfig,
	isAutomaticProcessConfig,
} from "./graph_post_processing";
import {
	isBoolean,
	isNumber,
} from "./utils";

/**
 * Interface is not intended to be instantiated.
 * Interface can be considered a map that defines available entry keys and the respective types.
 *
 * The actual shared data is managed via a StringIndexedInterface.
 */
interface SharedData {
	// [ms]; 0 disables timeout
	nestorTimeLimit: number;
	sheetMergingEnabled: boolean;
	automaticProcessConfig: AutomaticProcessConfig;
	prismNestingTimeLimit: number; // [milliseconds] 0 is considered no time limit
}

type SharedDataKey = keyof SharedData;

const typeGuardMap: {[index in SharedDataKey]: (arg: unknown) => arg is SharedData[index]} = {
	nestorTimeLimit: isNumber,
	sheetMergingEnabled: isBoolean,
	automaticProcessConfig: (arg: unknown): arg is AutomaticProcessConfig => isAutomaticProcessConfig(arg),
	prismNestingTimeLimit: isNumber,
};

const defaultValueMap: {[index in SharedDataKey]: SharedData[index]} = {
	nestorTimeLimit: 100,
	sheetMergingEnabled: true,
	automaticProcessConfig: {
		automaticDeburringEnabled: false,
		manualDeburringEnabled: false,
	},
	prismNestingTimeLimit: 100,
};

/**
 * Read value from shared data
 *
 * Returns default value in case it is not set.
 */
export function getSharedDataEntry<Key extends SharedDataKey>(key: Key, sharedData = wsi4.sharedData.read()): SharedData[Key] {
	const value = sharedData[key];
	if (!typeGuardMap[key](value)) {
		return defaultValueMap[key];
	} else {
		return value as SharedData[Key];
	}
}

/**
 * Create updated shared data
 *
 * Submitted value overwrites an existing value (if any).
 */
export function createUpdatedSharedData<Key extends SharedDataKey>(key: Key, value: SharedData[Key], sharedData = wsi4.sharedData.read()): StringIndexedInterface {
	sharedData[key] = value;
	return sharedData;
}
