// Stub for @oh-my-pi/pi-natives — provides minimal native bindings for pi-coding-agent
// used in Vividra's SDK context. Real N-API binaries are not needed.

import type { Ellipsis } from "@oh-my-pi/pi-tui";

// ---------------------------------------------------------------------------
// countTokens — critical stub for agent-session.ts:6205
// ---------------------------------------------------------------------------
export function countTokens(input: string | string[], _encoding?: Encoding | null): number {
	const text = Array.isArray(input) ? input.join(" ") : input;
	return Math.ceil(text.length / 4);
}

export enum Encoding {
	O200kBase = "O200kBase",
	Cl100kBase = "Cl100kBase",
}

// ---------------------------------------------------------------------------
// MacOSPowerAssertion — macOS-only, no-op on other platforms
// ---------------------------------------------------------------------------
export class MacOSPowerAssertion {
	static start(_options?: MacOSPowerAssertionOptions | null): MacOSPowerAssertion {
		return new MacOSPowerAssertion();
	}
	stop(): void {}
}

export interface MacOSPowerAssertionOptions {
	reason?: string;
	idle?: boolean;
	system?: boolean;
	user?: boolean;
	display?: boolean;
}

// ---------------------------------------------------------------------------
// MacAppearanceObserver
// ---------------------------------------------------------------------------
export class MacAppearanceObserver {
	static start(_callback: (err: null | Error, appearance: MacOSAppearance) => void): MacAppearanceObserver {
		return new MacAppearanceObserver();
	}
	stop(): void {}
}

export enum MacOSAppearance {
	Dark = "dark",
	Light = "light",
}

export function detectMacOSAppearance(): MacOSAppearance | null {
	return null;
}

// ---------------------------------------------------------------------------
// Process
// ---------------------------------------------------------------------------
export class Process {
	static fromPid(_pid: number): Process | null { return null; }
	static fromPath(_path: string): Process[] { return []; }
	get pid(): number { return 0; }
	get ppid(): number | null { return null; }
	args(): string[] { return []; }
	killTree(_signal?: number | null): number { return 0; }
	terminate(_options?: ProcessTerminateOptions | null): Promise<boolean> { return Promise.resolve(false); }
	waitForExit(_options?: ProcessWaitOptions | null): Promise<boolean> { return Promise.resolve(false); }
	groupId(): number | null { return null; }
	children(): Process[] { return []; }
	status(): ProcessStatus { return ProcessStatus.Exited; }
}

export enum ProcessStatus {
	Running = "running",
	Exited = "exited",
}

export interface ProcessTerminateOptions {
	group?: boolean;
	gracefulMs?: number;
	timeoutMs?: number;
	signal?: unknown;
}

export interface ProcessWaitOptions {
	timeoutMs?: number;
	signal?: unknown;
}

// ---------------------------------------------------------------------------
// PtySession
// ---------------------------------------------------------------------------
export class PtySession {
	constructor() {}
	async start(_options: PtyStartOptions, _onChunk?: ((error: Error | null, chunk: string) => void) | null): Promise<PtyRunResult> {
		return { exitCode: 0, cancelled: false, timedOut: false };
	}
	write(_data: string): void {}
	resize(_cols: number, _rows: number): void {}
	kill(): void {}
}

export interface PtyStartOptions {
	command: string;
	cwd?: string;
	env?: Record<string, string>;
	timeoutMs?: number;
	signal?: unknown;
	cols?: number;
	rows?: number;
	shell?: string;
}

export interface PtyRunResult {
	exitCode?: number;
	cancelled: boolean;
	timedOut: boolean;
}

// ---------------------------------------------------------------------------
// Shell
// ---------------------------------------------------------------------------
export class Shell {
	constructor(_options?: ShellOptions | null) {}
	async run(_options: ShellRunOptions, _onChunk?: ((error: Error | null, chunk: string) => void) | null): Promise<ShellRunResult> {
		return { exitCode: 0, cancelled: false, timedOut: false };
	}
	abort(): Promise<void> { return Promise.resolve(); }
}

export interface ShellOptions {
	sessionEnv?: Record<string, string>;
	snapshotPath?: string;
	minimizer?: MinimizerOptions;
}

export interface ShellRunOptions {
	command: string;
	cwd?: string;
	env?: Record<string, string>;
	timeoutMs?: number;
	signal?: unknown;
}

export interface ShellRunResult {
	exitCode?: number;
	cancelled: boolean;
	timedOut: boolean;
}

// ---------------------------------------------------------------------------
// executeShell
// ---------------------------------------------------------------------------
export async function executeShell(
	_options: ShellExecuteOptions,
	_onChunk?: ((error: Error | null, chunk: string) => void) | null
): Promise<ShellRunResult> {
	return { exitCode: 0, cancelled: false, timedOut: false };
}

export interface ShellExecuteOptions {
	command: string;
	cwd?: string;
	env?: Record<string, string>;
	sessionEnv?: Record<string, string>;
	timeoutMs?: number;
	snapshotPath?: string;
	minimizer?: MinimizerOptions;
	signal?: unknown;
}

// ---------------------------------------------------------------------------
// __piNativesV sentinel
// ---------------------------------------------------------------------------
export function __piNativesV15_11_0(): void {}

// ---------------------------------------------------------------------------
// applyBashFixups
// ---------------------------------------------------------------------------
export interface BashFixupResult {
	command: string;
	stripped: string[];
}

export function applyBashFixups(command: string): BashFixupResult {
	return { command, stripped: [] };
}

// ---------------------------------------------------------------------------
// astEdit / astGrep / astMatch
// ---------------------------------------------------------------------------
export interface AstFindMatch {
	path: string;
	text: string;
	byteStart: number;
	byteEnd: number;
	startLine: number;
	startColumn: number;
	endLine: number;
	endColumn: number;
	metaVariables?: Record<string, string>;
}

export interface AstFindOptions {
	patterns?: string[];
	lang?: string;
	path?: string;
	glob?: string;
	selector?: string;
	strictness?: AstMatchStrictness;
	limit?: number;
	offset?: number;
	includeMeta?: boolean;
	context?: number;
	signal?: unknown;
	timeoutMs?: number;
}

export interface AstFindResult {
	matches: AstFindMatch[];
	totalMatches: number;
	filesWithMatches: number;
	filesSearched: number;
	limitReached: boolean;
	parseErrors?: string[];
}

export function astGrep(_options: AstFindOptions): Promise<AstFindResult> {
	return Promise.resolve({ matches: [], totalMatches: 0, filesWithMatches: 0, filesSearched: 0, limitReached: false });
}

export interface AstMatchOptions {
	source: string;
	lang: string;
	patterns: string[];
	selector?: string;
	strictness?: AstMatchStrictness;
	limit?: number;
	offset?: number;
	includeMeta?: boolean;
	signal?: unknown;
	timeoutMs?: number;
}

export interface AstMatchResult {
	matches: AstFindMatch[];
	totalMatches: number;
	limitReached: boolean;
	parseErrors?: string[];
}

export function astMatch(_options: AstMatchOptions): Promise<AstMatchResult> {
	return Promise.resolve({ matches: [], totalMatches: 0, limitReached: false });
}

export interface AstReplaceChange {
	path: string;
	before: string;
	after: string;
	byteStart: number;
	byteEnd: number;
	deletedLength: number;
	startLine: number;
	startColumn: number;
	endLine: number;
	endColumn: number;
}

export interface AstReplaceFileChange {
	path: string;
	count: number;
}

export interface AstReplaceOptions {
	rewrites?: Record<string, string>;
	lang?: string;
	path?: string;
	glob?: string;
	selector?: string;
	strictness?: AstMatchStrictness;
	dryRun?: boolean;
	maxReplacements?: number;
	maxFiles?: number;
	failOnParseError?: boolean;
	signal?: unknown;
	timeoutMs?: number;
}

export interface AstReplaceResult {
	changes: AstReplaceChange[];
	fileChanges: AstReplaceFileChange[];
	totalReplacements: number;
	filesTouched: number;
	filesSearched: number;
	applied: boolean;
	limitReached: boolean;
	parseErrors?: string[];
}

export function astEdit(_options: AstReplaceOptions): Promise<AstReplaceResult> {
	return Promise.resolve({
		changes: [],
		fileChanges: [],
		totalReplacements: 0,
		filesTouched: 0,
		filesSearched: 0,
		applied: false,
		limitReached: false,
	});
}

export enum AstMatchStrictness {
	Cst = "cst",
	Smart = "smart",
	Ast = "ast",
	Relaxed = "relaxed",
	Signature = "signature",
	Template = "template",
}

// ---------------------------------------------------------------------------
// blockRangeAt
// ---------------------------------------------------------------------------
export interface BlockRange {
	startLine: number;
	endLine: number;
}

export interface BlockRangeOptions {
	code: string;
	lang?: string;
	path?: string;
	line: number;
}

export function blockRangeAt(_options: BlockRangeOptions): BlockRange | null { return null; }

// ---------------------------------------------------------------------------
// ClipboardImage
// ---------------------------------------------------------------------------
export interface ClipboardImage {
	data: Uint8Array;
	mimeType: string;
}

export function copyToClipboard(_text: string): void {}
export async function readImageFromClipboard(): Promise<ClipboardImage | undefined | null> { return null; }

// ---------------------------------------------------------------------------
// enclosingBlockBoundaries
// ---------------------------------------------------------------------------
export interface EnclosingBoundaryOptions {
	code: string;
	lang?: string;
	path?: string;
	ranges: LineRange[];
}

export function enclosingBlockBoundaries(_options: EnclosingBoundaryOptions): number[] | null { return null; }

// ---------------------------------------------------------------------------
// encodeSixel
// ---------------------------------------------------------------------------
export function encodeSixel(_bytes: Uint8Array, _targetWidthPx: number, _targetHeightPx: number): string { return ""; }

// ---------------------------------------------------------------------------
// extractSegments
// ---------------------------------------------------------------------------
export interface ExtractSegmentsResult_ {
	before: string;
	beforeWidth: number;
	after: string;
	afterWidth: number;
}

export function extractSegments(_line: string, _beforeEnd: number, _afterStart: number, _afterLen: number, _strictAfter: boolean, _tabWidth: number): ExtractSegmentsResult_ {
	return { before: "", beforeWidth: 0, after: "", afterWidth: 0 };
}

// ---------------------------------------------------------------------------
// FileType
// ---------------------------------------------------------------------------
export enum FileType {
	File = 1,
	Dir = 2,
	Symlink = 3,
}

// ---------------------------------------------------------------------------
// FuzzyFind
// ---------------------------------------------------------------------------
export interface FuzzyFindMatch {
	path: string;
	isDirectory: boolean;
	score: number;
}

export interface FuzzyFindOptions {
	query: string;
	path: string;
	hidden?: boolean;
	gitignore?: boolean;
	cache?: boolean;
	maxResults?: number;
	signal?: unknown;
	timeoutMs?: number;
}

export interface FuzzyFindResult {
	matches: FuzzyFindMatch[];
	totalMatches: number;
}

export function fuzzyFind(_options: FuzzyFindOptions): Promise<FuzzyFindResult> {
	return Promise.resolve({ matches: [], totalMatches: 0 });
}

// ---------------------------------------------------------------------------
// getSupportedLanguages
// ---------------------------------------------------------------------------
export function getSupportedLanguages(): string[] { return []; }

// ---------------------------------------------------------------------------
// getWorkProfile
// ---------------------------------------------------------------------------
export interface WorkProfile {
	folded: string;
	summary: string;
	svg?: string;
	totalMs: number;
	sampleCount: number;
}

export function getWorkProfile(_lastSeconds: number): WorkProfile {
	return { folded: "", summary: "", totalMs: 0, sampleCount: 0 };
}

// ---------------------------------------------------------------------------
// glob
// ---------------------------------------------------------------------------
export interface GlobMatch {
	path: string;
	fileType: FileType;
	mtime?: number;
	size?: number;
}

export interface GlobOptions {
	pattern: string;
	path: string;
	fileType?: FileType;
	recursive?: boolean;
	hidden?: boolean;
	maxResults?: number;
	gitignore?: boolean;
	cache?: boolean;
	sortByMtime?: boolean;
	includeNodeModules?: boolean;
	signal?: unknown;
	timeoutMs?: number;
}

export interface GlobResult {
	matches: GlobMatch[];
	totalMatches: number;
}

export function glob(_options: GlobOptions, _onMatch?: ((error: Error | null, match: GlobMatch) => void) | null): Promise<GlobResult> {
	return Promise.resolve({ matches: [], totalMatches: 0 });
}

// ---------------------------------------------------------------------------
// grep
// ---------------------------------------------------------------------------
export interface GrepMatch {
	path: string;
	lineNumber: number;
	line: string;
	contextBefore?: ContextLine[];
	contextAfter?: ContextLine[];
	truncated?: boolean;
	matchCount?: number;
}

export interface ContextLine {
	lineNumber: number;
	line: string;
}

export interface GrepOptions {
	pattern: string;
	path: string;
	glob?: string;
	type?: string;
	ignoreCase?: boolean;
	multiline?: boolean;
	hidden?: boolean;
	gitignore?: boolean;
	cache?: boolean;
	maxCount?: number;
	offset?: number;
	contextBefore?: number;
	contextAfter?: number;
	context?: number;
	maxColumns?: number;
	mode?: GrepOutputMode;
	maxCountPerFile?: number;
	signal?: unknown;
	timeoutMs?: number;
}

export enum GrepOutputMode {
	Content = "content",
	Count = "count",
	FilesWithMatches = "filesWithMatches",
}

export interface GrepResult {
	matches: GrepMatch[];
	totalMatches: number;
	filesWithMatches: number;
	filesSearched: number;
	limitReached?: boolean;
	skippedOversized?: number;
}

export function grep(_options: GrepOptions, _onMatch?: ((error: Error | null, match: GrepMatch) => void) | null): Promise<GrepResult> {
	return Promise.resolve({ matches: [], totalMatches: 0, filesWithMatches: 0, filesSearched: 0 });
}

// ---------------------------------------------------------------------------
// hasMatch
// ---------------------------------------------------------------------------
export function hasMatch(_content: string | Uint8Array, _pattern: string | Uint8Array, _ignoreCase?: boolean | null, _multiline?: boolean | null): boolean { return false; }

// ---------------------------------------------------------------------------
// highlightCode
// ---------------------------------------------------------------------------
export interface HighlightColors {
	comment: string;
	keyword: string;
	function: string;
	variable: string;
	string: string;
	number: string;
	type: string;
	operator: string;
	punctuation: string;
	inserted?: string;
	deleted?: string;
}

export function highlightCode(_code: string, _lang: string | null, _colors: HighlightColors): string { return _code; }

// ---------------------------------------------------------------------------
// htmlToMarkdown
// ---------------------------------------------------------------------------
export interface HtmlToMarkdownOptions {
	cleanContent?: boolean;
	skipImages?: boolean;
}

export function htmlToMarkdown(_html: string, _options?: HtmlToMarkdownOptions | null): Promise<string> { return Promise.resolve(""); }

// ---------------------------------------------------------------------------
// invalidateFsScanCache
// ---------------------------------------------------------------------------
export function invalidateFsScanCache(_path?: string | null): void {}

// ---------------------------------------------------------------------------
// iso* functions
// ---------------------------------------------------------------------------
export enum IsoBackendKind {
	Apfs = 0,
	Btrfs = 1,
	Zfs = 2,
	LinuxReflink = 3,
	Overlayfs = 4,
	WindowsBlockClone = 5,
	Projfs = 6,
	Rcopy = 7,
}

export enum IsoChangeKind {
	Added = 0,
	Modified = 1,
	Removed = 2,
}

export interface IsoDiff {
	files: IsoFileChange[];
}

export interface IsoFileChange {
	path: string;
	op: IsoChangeKind;
	diff?: string;
}

export interface IsoProbeResult {
	available: boolean;
	reason?: string;
	kind: IsoBackendKind;
}

export interface IsoResolveResult {
	kind: IsoBackendKind;
	candidates: IsoBackendKind[];
	fellBack: boolean;
	reason?: string;
}

export function isoBackend(): IsoBackendKind { return IsoBackendKind.Projfs; }
export function isoDiff(_lower: string, _merged: string): Promise<IsoDiff> { return Promise.resolve({ files: [] }); }
export function isoIsUnavailableError(_message: string): boolean { return false; }
export function isoProbe(_kind?: IsoBackendKind | null): IsoProbeResult { return { available: false, kind: IsoBackendKind.Projfs }; }
export function isoResolve(_preferred?: IsoBackendKind | null): IsoResolveResult { return { kind: IsoBackendKind.Projfs, candidates: [IsoBackendKind.Projfs], fellBack: false }; }
export function isoStart(_kind: IsoBackendKind | null, _lower: string, _merged: string): Promise<void> { return Promise.resolve(); }
export function isoStop(_kind: IsoBackendKind | null, _merged: string): Promise<void> { return Promise.resolve(); }

// ---------------------------------------------------------------------------
// LineRange
// ---------------------------------------------------------------------------
export interface LineRange {
	startLine: number;
	endLine: number;
}

// ---------------------------------------------------------------------------
// listWorkspace
// ---------------------------------------------------------------------------
export interface ListWorkspaceOptions {
	path: string;
	maxDepth: number;
	hidden?: boolean;
	gitignore?: boolean;
	collectAgentsMd?: boolean;
	timeoutMs?: number;
	signal?: unknown;
}

export interface ListWorkspaceResult {
	entries: GlobMatch[];
	agentsMdFiles: string[];
	truncated: boolean;
}

export function listWorkspace(_options: ListWorkspaceOptions): Promise<ListWorkspaceResult> {
	return Promise.resolve({ entries: [], agentsMdFiles: [], truncated: false });
}

// ---------------------------------------------------------------------------
// Match
// ---------------------------------------------------------------------------
export interface Match {
	lineNumber: number;
	line: string;
	contextBefore?: ContextLine[];
	contextAfter?: ContextLine[];
	truncated?: boolean;
}

// ---------------------------------------------------------------------------
// matchesKey
// ---------------------------------------------------------------------------
export function matchesKey(_data: string, _keyId: string, _kittyProtocolActive: boolean): boolean { return false; }
export function matchesKittySequence(_data: string, _expectedCodepoint: number, _expectedModifier: number): boolean { return false; }
export function matchesLegacySequence(_data: string, _keyName: string): boolean { return false; }

// ---------------------------------------------------------------------------
// MinimizerOptions / MinimizerResult
// ---------------------------------------------------------------------------
export interface MinimizerOptions {
	enabled?: boolean;
	settingsPath?: string;
	settingsHash?: string;
	only?: string[];
	except?: string[];
	maxCaptureBytes?: number;
	sourceOutlineLevel?: string;
	legacyFilters?: boolean;
}

export interface MinimizerResult {
	filter: string;
	text: string;
	originalText: string;
	inputBytes: number;
	outputBytes: number;
}

// ---------------------------------------------------------------------------
// parseKey / parseKittySequence
// ---------------------------------------------------------------------------
export interface ParsedKittyResult {
	codepoint: number;
	shiftedKey?: number;
	baseLayoutKey?: number;
	modifier: number;
	eventType?: number;
}

export function parseKey(_data: string, _kittyProtocolActive: boolean): string | null { return null; }
export function parseKittySequence(_data: string): ParsedKittyResult | null { return null; }

// ---------------------------------------------------------------------------
// readImageFromClipboard — already defined above

// ---------------------------------------------------------------------------
// renderSnapcompactPng
// ---------------------------------------------------------------------------
export interface SnapcompactRenderOptions {
	size: number;
	font?: string;
	cellWidth?: number;
	cellHeight?: number;
	variant?: string;
	lineRepeat?: number;
}

export function renderSnapcompactPng(_text: string, _options: SnapcompactRenderOptions): string { return ""; }

// ---------------------------------------------------------------------------
// search
// ---------------------------------------------------------------------------
export interface SearchOptions {
	pattern: string;
	ignoreCase?: boolean;
	multiline?: boolean;
	maxCount?: number;
	offset?: number;
	contextBefore?: number;
	contextAfter?: number;
	context?: number;
	maxColumns?: number;
	mode?: GrepOutputMode;
}

export interface SearchResult {
	matches: Match[];
	matchCount: number;
	limitReached: boolean;
	error?: string;
}

export function search(_content: string | Uint8Array, _options: SearchOptions): SearchResult {
	return { matches: [], matchCount: 0, limitReached: false };
}

// ---------------------------------------------------------------------------
// sliceWithWidth
// ---------------------------------------------------------------------------
export interface SliceResult {
	text: string;
	width: number;
}

export function sliceWithWidth(_line: string, _startCol: number, _length: number, _strict: boolean | null | undefined, _tabWidth: number): SliceResult {
	return { text: "", width: 0 };
}

// ---------------------------------------------------------------------------
// summarizeCode
// ---------------------------------------------------------------------------
export interface SummaryOptions {
	code: string;
	lang?: string;
	path?: string;
	minBodyLines?: number;
	minCommentLines?: number;
	unfoldUntilLines?: number;
	unfoldLimitLines?: number;
}

export interface SummaryResult {
	language?: string;
	parsed: boolean;
	elided: boolean;
	totalLines: number;
	segments: SummarySegment[];
}

export interface SummarySegment {
	kind: string;
	startLine: number;
	endLine: number;
	text?: string;
}

export function summarizeCode(_options: SummaryOptions): SummaryResult {
	return { parsed: false, elided: false, totalLines: 0, segments: [] };
}

// ---------------------------------------------------------------------------
// supportsLanguage
// ---------------------------------------------------------------------------
export function supportsLanguage(_lang: string): boolean { return false; }

// ---------------------------------------------------------------------------
// truncateToWidth
// ---------------------------------------------------------------------------
export function truncateToWidth(_text: string, _maxWidth: number, _ellipsisKind: Ellipsis | null | undefined, _pad: boolean | null | undefined, _tabWidth: number): string {
	return _text;
}

// ---------------------------------------------------------------------------
// visibleWidth
// ---------------------------------------------------------------------------
export function visibleWidth(_text: string, _tabWidth: number): number { return _text.length; }

// ---------------------------------------------------------------------------
// wrapTextWithAnsi
// ---------------------------------------------------------------------------
export function wrapTextWithAnsi(_text: string, _width: number, _tabWidth: number): string[] { return [_text]; }