declare module "@ap-mitch/pcsclite" {
	import { EventEmitter } from "events";

	type ConnectOptions = {
		share_mode?: number;
		protocol?: number;
	};

	type Status = {
		atr?: Buffer;
		state: number;
	};

	type AnyOrNothing = any | undefined | null;

	export interface PCSCLite extends EventEmitter {
		on(type: "error", listener: (error: any) => void): this;

		once(type: "error", listener: (error: any) => void): this;

		on(type: "reader", listener: (reader: CardReader) => void): this;

		once(type: "reader", listener: (reader: CardReader) => void): this;

		close(): void;
	}

	export interface CardReader extends EventEmitter {
		// Share Mode
		SCARD_SHARE_SHARED: number;
		SCARD_SHARE_EXCLUSIVE: number;
		SCARD_SHARE_DIRECT: number;
		// Protocol
		SCARD_PROTOCOL_T0: number;
		SCARD_PROTOCOL_T1: number;
		SCARD_PROTOCOL_RAW: number;
		//  State
		SCARD_STATE_UNAWARE: number;
		SCARD_STATE_IGNORE: number;
		SCARD_STATE_CHANGED: number;
		SCARD_STATE_UNKNOWN: number;
		SCARD_STATE_UNAVAILABLE: number;
		SCARD_STATE_EMPTY: number;
		SCARD_STATE_PRESENT: number;
		SCARD_STATE_ATRMATCH: number;
		SCARD_STATE_EXCLUSIVE: number;
		SCARD_STATE_INUSE: number;
		SCARD_STATE_MUTE: number;
		// Disconnect disposition
		SCARD_LEAVE_CARD: number;
		SCARD_RESET_CARD: number;
		SCARD_UNPOWER_CARD: number;
		SCARD_EJECT_CARD: number;
		name: string;
		state: number;
		connected: boolean;

		on(
			type: "error",
			listener: (this: CardReader, error: any) => void
		): this;

		once(
			type: "error",
			listener: (this: CardReader, error: any) => void
		): this;

		on(type: "end", listener: (this: CardReader) => void): this;

		once(type: "end", listener: (this: CardReader) => void): this;

		on(
			type: "status",
			listener: (this: CardReader, status: Status) => void
		): this;

		once(
			type: "status",
			listener: (this: CardReader, status: Status) => void
		): this;

		SCARD_CTL_CODE(code: number): number;

		get_status(
			cb: (err: AnyOrNothing, state: number, atr?: Buffer) => void
		): void;

		connect(callback: (err: AnyOrNothing, protocol: number) => void): void;

		connect(
			options: ConnectOptions,
			callback: (err: AnyOrNothing, protocol: number) => void
		): void;

		disconnect(callback: (err: AnyOrNothing) => void): void;

		disconnect(
			disposition: number,
			callback: (err: AnyOrNothing) => void
		): void;

		transmit(
			data: Buffer,
			res_len: number,
			protocol: number,
			cb: (err: AnyOrNothing, response: Buffer) => void
		): void;

		control(
			data: Buffer,
			control_code: number,
			res_len: number,
			cb: (err: AnyOrNothing, response: Buffer) => void
		): void;

		close(): void;
	}

	export function pcsc(): PCSCLite;
}
