// SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>
// SPDX-License-Identifier: GPL-3.0-or-later

declare global {
	interface Window {
		NanoPow: typeof NanoPow
	}
}

declare const NanoPow: typeof NanoPowGl | typeof NanoPowGpu | null

/**
* Nano proof-of-work using WebGL 2.0.
*/
export declare class NanoPowGl {
	#private
	/**
	* Constructs canvas, gets WebGL context, initializes buffers, and compiles
	* shaders.
	*/
	static init (): Promise<void>
	/**
	* On WebGL context loss, attempts to clear all program variables and then
	* reinitialize them by calling `init()`.
	*/
	static reset (): void
	/**
	* Finds a nonce that satisfies the Nano proof-of-work requirements.
	*
	* @param {string} hash - Hexadecimal hash of previous block, or public key for new accounts
	* @param {NanoPowOptions} options - Options used to configure search execution
	*/
	static work_generate (hash: string, options?: NanoPowOptions): Promise<WorkGenerateResponse>
	/**
	* Validates that a nonce satisfies Nano proof-of-work requirements.
	*
	* @param {string} work - Hexadecimal proof-of-work value to validate
	* @param {string} hash - Hexadecimal hash of previous block, or public key for new accounts
	* @param {NanoPowOptions} options - Options used to configure search execution
	*/
	static work_validate (work: string, hash: string, options?: NanoPowOptions): Promise<WorkValidateResponse>
}

/**
* Nano proof-of-work using WebGPU.
*/
export declare class NanoPowGpu {
	#private
	static init (): Promise<void>
	static reset (): void
	/**
	* Finds a nonce that satisfies the Nano proof-of-work requirements.
	*
	* @param {string} hash - Hexadecimal hash of previous block, or public key for new accounts
	* @param {NanoPowOptions} options - Used to configure search execution
	*/
	static work_generate (hash: string, options?: NanoPowOptions): Promise<WorkGenerateResponse>
	/**
	* Validates that a nonce satisfies Nano proof-of-work requirements.
	*
	* @param {string} work - Hexadecimal proof-of-work value to validate
	* @param {string} hash - Hexadecimal hash of previous block, or public key for new accounts
	* @param {NanoPowOptions} options - Options used to configure search execution
	*/
	static work_validate (work: string, hash: string, options?: NanoPowOptions): Promise<WorkValidateResponse>
}

/**
* Used to configure NanoPow.
*
* @param {boolean} [debug=false] - Enables additional debug logging to the console. Default: false
* @param {number} [effort=0x8] - Multiplier for dispatching work search. Larger values are not necessarily better since they can quickly overwhelm the GPU. Ignored when validating. Default: 0x8
* @param {bigint|string} [difficulty=0xfffffff800000000] - Minimum value result of `BLAKE2b(nonce||blockhash)`. Default: 0xFFFFFFF800000000
*/
export type NanoPowOptions = {
	debug?: boolean
	effort?: number
	difficulty?: bigint | string
}

export type NanoPowResult = {
	found: boolean
	work: bigint
	difficulty: bigint
}

/**
* Used to create WebGL framebuffer objects.
*
* @param {WebGLTexture} texture - Defines storage size
* @param {WebGLFramebuffer} framebuffer - Holds texture data
* @param {size} size - 2D lengths of texture
*/
export type FBO = {
	texture: WebGLTexture
	framebuffer: WebGLFramebuffer
	size: {
		x: number
		y: number
	}
}

/**
* Used to define NanoPow server configuration.
*
* @param {boolean} DEBUG - Enables additional log output
* @param {number} EFFORT - Defines dispatch size per compute pass
* @param {number} PORT - TCP port on which to listen for requests
*/
export type NanoPowServerConfig = {
	[key: string]: boolean | number
	DEBUG: boolean
	EFFORT: number
	PORT: number
}

export declare const NanoPowGlDownsampleShader: string
export declare const NanoPowGlDrawShader: string
export declare const NanoPowGlVertexShader: string
export declare const NanoPowGpuComputeShader: any

/**
* Used by work server for inbound requests to `work_generate`.
*
* @param {string} action - Method to call
* @param {string} hash - Block hash used to generate work
* @param {string} [difficulty=FFFFFFF800000000] - Minimum threshold for a nonce to be valid
*/
type WorkGenerateRequest = {
	[key: string]: string | undefined
	action: 'work_generate'
	hash: string
	difficulty?: string
}

/**
* Used by work server for outbound responses to `work_generate`.
*
* @param {string} hash - Block hash used to generate or validate work
* @param {string} work - Valid proof-of-work nonce generated for input hash
* @param {string} difficulty - BLAKE2b hash result which was compared to specified minimum threshold
*/
type WorkGenerateResponse = {
	[key: string]: string
	hash: string
	work: string
	difficulty: string
}

/**
* Used by work server for inbound requests to `work_validate`.
*
* @param {string} action - Method to call
* @param {string} hash - Block hash used to validate work
* @param {string} work - Existing nonce to check against hash
* @param {string} [difficulty=FFFFFFF800000000] - Minimum threshold for a nonce to be valid
*/
type WorkValidateRequest = {
	[key: string]: string | undefined
	action: 'work_validate'
	hash: string
	work: string
	difficulty?: string
}

/**
* Used by work server for outbound responses to `work_validate`.
*
* @param {string} hash - Hash from validate request
* @param {string} work - Nonce from validate request
* @param {string} difficulty - BLAKE2b hash result which is compared to specified minimum threshold
* @param {string} [valid] - Excluded if optional difficulty was not included in the request. 1 for true if nonce is valid for requested difficulty, else 0 for false
* @param {string} valid_all - 1 for true if nonce is valid for send blocks, else 0 for false
* @param {string} valid_receive - 1 for true if nonce is valid for receive blocks, else 0 for false
*/
type WorkValidateResponse = {
	[key: string]: string | undefined
	hash: string
	work: string
	difficulty: string
	valid?: '0' | '1'
	valid_all: '0' | '1'
	valid_receive: '0' | '1'
}
