
// generated by vicinae figura codegen - do not edit manually

interface JsonRpcMessage {
	jsonrpc: "2.0";
	method?: string;
	id?: number;
	params?: Record<string, any>;
	result?: any;
	error?: any;
}

interface ITransport {
	send(data: string): void;
}

type EventSubscription = {
	unsubscribe: () => void;
};

export class RpcTransport {
	constructor(private readonly transport: ITransport) { }

	dispatchMessage(data: string) {
		const msg = JSON.parse(data) as JsonRpcMessage;

		if (msg.id !== undefined) {
			const handler = this.requestMap.get(msg.id);

			if (handler) {
				if (msg.error) handler.reject(msg.error);
				else handler.resolve(msg.result);
				this.requestMap.delete(msg.id);
			}
		}
		if (msg.id === undefined && msg.method) {
			for (const cb of this.handlers.get(msg.method) ?? []) {
				cb(msg.params);
			}
		}
	}

	request<T>(method: string, params: Record<string, any>): Promise<T> {
		const id = this.id++;
		const promise = new Promise<T>((resolve, reject) => {
			this.requestMap.set(id, { resolve: (msg) => resolve(msg as T), reject });
		});

		this.sendMessage({ jsonrpc: '2.0', id, method, params });

		return promise;
	}

	subscribe(method: string, cb: (result: any) => void): EventSubscription {
		const handlers = this.handlers.get(method);

		if (handlers) handlers.push(cb);
		else this.handlers.set(method, [cb]);

		return {
			unsubscribe: () => {
				const handlers = this.handlers.get(method);

				if (handlers) {
					handlers.splice(handlers.indexOf(cb), 1);
				}
			},
		};
	}

	private sendMessage(msg: JsonRpcMessage) {
		this.transport.send(JSON.stringify(msg));
	}


	private id = 1;
	private requestMap = new Map<number, { resolve: (value: any) => void, reject: (error: any) => void }>;
	private handlers = new Map<string, Array<(result: any) => void>>;
};

export type ImageMask = 'None' | 'Circle' | 'RoundedRectangle';

export type ToastStyle = 'Success' | 'Info' | 'Warning' | 'Error' | 'Dynamic';

export type PopToRootType = 'Default' | 'Immediate' | 'Suspended';

export type ConfirmAlertActionStyle = 'Default' | 'Destructive' | 'Cancel';

export type NotificationUrgency = 'Low' | 'Normal' | 'High';

export type FileSearchCategory = 'Other' | 'Directory' | 'Image' | 'Video' | 'Audio' | 'Document' | 'Archive' | 'Application';

export type WallpaperFit = 'Cover' | 'Contain' | 'Stretch' | 'Center' | 'Tile';

export type Application = {
	id: string;
	name: string;
	icon?: string;
	path: string;
}

export type RunInTerminalPayload = {
	cmdline: string[];
	hold: boolean;
	appId?: string;
	workingDirectory?: string;
	title?: string;
}

export type ThemedImageSource = {
	light?: string;
	dark?: string;
}

export type ImageSource = {
	raw?: string;
	themed?: ThemedImageSource;
}

export type DynamicColor = {
	light: string;
	dark: string;
	adjustContrast?: boolean;
}

export type ColorLike = {
	raw?: string;
	dynamic?: DynamicColor;
}

export type Image = {
	source?: ImageSource;
	fallback?: ImageSource;
	mask?: ImageMask;
	tintColor?: ColorLike;
	fileIcon?: string;
}

export type ConfirmAlertAction = {
	title: string;
	style: ConfirmAlertActionStyle;
}

export type ConfirmAlertPayload = {
	title: string;
	description: string;
	primaryAction: ConfirmAlertAction;
	dismissAction: ConfirmAlertAction;
	rememberUserChoice: boolean;
	icon?: Image;
}

export type DesktopNotificationPayload = {
	title: string;
	body: string;
	icon?: Image;
	urgency: NotificationUrgency;
}

export type Rect = {
	x: number;
	y: number;
	width: number;
	height: number;
}

export type Size = {
	width: number;
	height: number;
}

export type Window = {
	id: string;
	title: string;
	workspaceId: string;
	active: boolean;
	fullscreen: boolean;
	bounds: Rect;
	app?: Application;
}

export type Screen = {
	name: string;
	model: string;
	make: string;
	serial?: string;
	bounds: Rect;
	physicalResolution: Size;
	active: boolean;
}

export type Workspace = {
	id: string;
	name: string;
	active: boolean;
	fullscreen: boolean;
	monitor?: string;
}

export type ClipboardContent = {
	text?: string;
	html?: string;
	urls?: string[];
}

export type ClipboardOptions = {
	concealed: boolean;
}

export type FileInfo = {
	path: string;
	category: FileSearchCategory;
	mimeType?: string;
}

export type FileSearchFilters = {
	category?: FileSearchCategory;
}

export type FileSearchOptions = {
	filters: FileSearchFilters;
	limit: number;
}

export type UpdateCommandMetadataPayload = {
	subtitle?: string;
}

export type PKCEClientOptions = {
	name: string;
	id?: string;
	description: string;
	icon?: Image;
}

export type AuthorizeRequest = {
	client: PKCEClientOptions;
	url: string;
}

export type AuthorizeResponse = {
	code: string;
}

export type TokenSet = {
	accessToken: string;
	refreshToken?: string;
	idToken?: string;
	expiresIn?: number;
	scope?: string;
	updatedAt: number;
}

export type SetTokensRequest = {
	providerId?: string;
	accessToken: string;
	refreshToken?: string;
	idToken?: string;
	expiresIn?: number;
	scope?: string;
}

export type TokenSetResponse = {
	set?: TokenSet;
}

export type SetWallpaperOptions = {
	fit?: WallpaperFit;
	screen?: string;
}

export type BrowserTab = {
	id: number;
	title?: string;
	url: string;
	active: boolean;
	browserId: string;
}

class ApplicationService {
	constructor(private readonly transport: RpcTransport) {}

	list(target?: string): Promise<Application[]> {
		return this.transport.request("Application/list", { target});	
	}

	open(target: string, appId?: string): Promise<void> {
		return this.transport.request("Application/open", { target, appId});	
	}

	getDefault(target: string): Promise<Application> {
		return this.transport.request("Application/getDefault", { target});	
	}

	showInFileBrowser(target: string, select: boolean): Promise<void> {
		return this.transport.request("Application/showInFileBrowser", { target, select});	
	}

	runInTerminal(opts: RunInTerminalPayload): Promise<boolean> {
		return this.transport.request("Application/runInTerminal", { opts});	
	}

}

class UIService {
	constructor(private readonly transport: RpcTransport) {}

	render(json: string): Promise<void> {
		return this.transport.request("UI/render", { json});	
	}

	showToast(id: string, title: string, message: string, style: ToastStyle): Promise<void> {
		return this.transport.request("UI/showToast", { id, title, message, style});	
	}

	updateToast(id: string, title: string): Promise<void> {
		return this.transport.request("UI/updateToast", { id, title});	
	}

	hideToast(id: string): Promise<void> {
		return this.transport.request("UI/hideToast", { id});	
	}

	showHud(text: string, clear_root: boolean, popToRoot: PopToRootType): Promise<void> {
		return this.transport.request("UI/showHud", { text, clear_root, popToRoot});	
	}

	closeMainWindow(clearRoot: boolean, popToRoot: PopToRootType): Promise<void> {
		return this.transport.request("UI/closeMainWindow", { clearRoot, popToRoot});	
	}

	popToRoot(clearSearchBar: boolean): Promise<void> {
		return this.transport.request("UI/popToRoot", { clearSearchBar});	
	}

	confirmAlert(payload: ConfirmAlertPayload): Promise<boolean> {
		return this.transport.request("UI/confirmAlert", { payload});	
	}

	pushView(): Promise<void> {
		return this.transport.request("UI/pushView", { });	
	}

	popView(): Promise<void> {
		return this.transport.request("UI/popView", { });	
	}

	setSearchText(text: string): Promise<void> {
		return this.transport.request("UI/setSearchText", { text});	
	}

	getSelectedText(): Promise<string> {
		return this.transport.request("UI/getSelectedText", { });	
	}

	sendDesktopNotification(data: DesktopNotificationPayload): Promise<void> {
		return this.transport.request("UI/sendDesktopNotification", { data});	
	}

	viewPoped(handler: () => void): EventSubscription {
		return this.transport.subscribe("UI/viewPoped", (msg) => handler())
	}
	viewPushed(handler: () => void): EventSubscription {
		return this.transport.subscribe("UI/viewPushed", (msg) => handler())
	}
}

class WindowManagementService {
	constructor(private readonly transport: RpcTransport) {}

	focusWindow(winId: string): Promise<boolean> {
		return this.transport.request("WindowManagement/focusWindow", { winId});	
	}

	getActiveWindow(): Promise<Window> {
		return this.transport.request("WindowManagement/getActiveWindow", { });	
	}

	getActiveWorkspace(): Promise<Workspace> {
		return this.transport.request("WindowManagement/getActiveWorkspace", { });	
	}

	getWindows(workspaceId?: string): Promise<Window[]> {
		return this.transport.request("WindowManagement/getWindows", { workspaceId});	
	}

	getScreens(): Promise<Screen[]> {
		return this.transport.request("WindowManagement/getScreens", { });	
	}

	getWorkspaces(): Promise<Workspace[]> {
		return this.transport.request("WindowManagement/getWorkspaces", { });	
	}

	setWindowBounds(winId: string, bounds: Rect): Promise<void> {
		return this.transport.request("WindowManagement/setWindowBounds", { winId, bounds});	
	}

}

class ClipboardService {
	constructor(private readonly transport: RpcTransport) {}

	copy(content: ClipboardContent, options: ClipboardOptions): Promise<void> {
		return this.transport.request("Clipboard/copy", { content, options});	
	}

	paste(content: ClipboardContent): Promise<void> {
		return this.transport.request("Clipboard/paste", { content});	
	}

	clear(): Promise<void> {
		return this.transport.request("Clipboard/clear", { });	
	}

	readContent(): Promise<ClipboardContent> {
		return this.transport.request("Clipboard/readContent", { });	
	}

}

class StorageService {
	constructor(private readonly transport: RpcTransport) {}

	get(key: string): Promise<any> {
		return this.transport.request("Storage/get", { key});	
	}

	set(key: string, value: any): Promise<void> {
		return this.transport.request("Storage/set", { key, value});	
	}

	remove(key: string): Promise<void> {
		return this.transport.request("Storage/remove", { key});	
	}

	clear(): Promise<void> {
		return this.transport.request("Storage/clear", { });	
	}

	list(): Promise<any> {
		return this.transport.request("Storage/list", { });	
	}

}

class FileSearchService {
	constructor(private readonly transport: RpcTransport) {}

	search(q: string, opts: FileSearchOptions): Promise<FileInfo[]> {
		return this.transport.request("FileSearch/search", { q, opts});	
	}

}

class CommandService {
	constructor(private readonly transport: RpcTransport) {}

	updateCommandMetadata(payload: UpdateCommandMetadataPayload): Promise<void> {
		return this.transport.request("Command/updateCommandMetadata", { payload});	
	}

	openExtensionPreferences(): Promise<void> {
		return this.transport.request("Command/openExtensionPreferences", { });	
	}

	openCommandPreferences(): Promise<void> {
		return this.transport.request("Command/openCommandPreferences", { });	
	}

}

class OAuthService {
	constructor(private readonly transport: RpcTransport) {}

	authorize(payload: AuthorizeRequest): Promise<AuthorizeResponse> {
		return this.transport.request("OAuth/authorize", { payload});	
	}

	getTokens(id?: string): Promise<TokenSetResponse> {
		return this.transport.request("OAuth/getTokens", { id});	
	}

	setTokens(payload: SetTokensRequest): Promise<void> {
		return this.transport.request("OAuth/setTokens", { payload});	
	}

	removeTokens(id?: string): Promise<void> {
		return this.transport.request("OAuth/removeTokens", { id});	
	}

}

class WallpaperService {
	constructor(private readonly transport: RpcTransport) {}

	set(path: string, options: SetWallpaperOptions): Promise<void> {
		return this.transport.request("Wallpaper/set", { path, options});	
	}

}

class BrowserExtensionService {
	constructor(private readonly transport: RpcTransport) {}

	getTabs(): Promise<BrowserTab[]> {
		return this.transport.request("BrowserExtension/getTabs", { });	
	}

	focusTab(browserId: string, tabId: number): Promise<void> {
		return this.transport.request("BrowserExtension/focusTab", { browserId, tabId});	
	}

}

class EventCoreService {
	constructor(private readonly transport: RpcTransport) {}

	handlerActivated(handler: (id: string, args: any[]) => void): EventSubscription {
		return this.transport.subscribe("EventCore/handlerActivated", (msg) => handler(msg.id, msg.args))
	}
}

export class Client {
	constructor(private readonly transport: RpcTransport) {
		this.Application = new ApplicationService(this.transport);
		this.UI = new UIService(this.transport);
		this.WindowManagement = new WindowManagementService(this.transport);
		this.Clipboard = new ClipboardService(this.transport);
		this.Storage = new StorageService(this.transport);
		this.FileSearch = new FileSearchService(this.transport);
		this.Command = new CommandService(this.transport);
		this.OAuth = new OAuthService(this.transport);
		this.Wallpaper = new WallpaperService(this.transport);
		this.BrowserExtension = new BrowserExtensionService(this.transport);
		this.EventCore = new EventCoreService(this.transport);
	}

  	route(msg: string): void { this.transport.dispatchMessage(msg); }
  	Application: ApplicationService;
	UI: UIService;
	WindowManagement: WindowManagementService;
	Clipboard: ClipboardService;
	Storage: StorageService;
	FileSearch: FileSearchService;
	Command: CommandService;
	OAuth: OAuthService;
	Wallpaper: WallpaperService;
	BrowserExtension: BrowserExtensionService;
	EventCore: EventCoreService;

}
