<commit_before>import * as os from 'os';
import * as path from 'path';
import { accessSync, X_OK } from 'fs';
import { connect, Socket } from 'net';
import { spawn, ChildProcess } from 'child_process';
import { LaunchConfiguration } from '../adapter/launchConfiguration';

export function launchFirefox(config: LaunchConfiguration, 
	convertPathToFirefoxUrl: (path: string) => string): ChildProcess | string {

	let firefoxPath = getFirefoxExecutablePath(config);	
	
	let port = config.port || 6000;
	let firefoxArgs: string[] = [ '-start-debugger-server', String(port), '-no-remote' ];
	if (config.profile) {
		firefoxArgs.push('-P', config.profile);
	}
	if (Array.isArray(config.firefoxArgs)) {
		firefoxArgs = firefoxArgs.concat(config.firefoxArgs);
	}
	if (config.file) {
		if (!path.isAbsolute(config.file)) {
			return 'The "file" property in the launch configuration has to be an absolute path';
		}
		firefoxArgs.push(convertPathToFirefoxUrl(config.file));
	} else if (config.url) {
		firefoxArgs.push(config.url);
	} else {
		return 'You need to set either "file" or "url" in the launch configuration';
	}
	
	let childProc = spawn(firefoxPath, firefoxArgs, { detached: true, stdio: 'ignore' });
	childProc.unref();
	return childProc;
}

export function waitForSocket(config: LaunchConfiguration): Promise<Socket> {
	let port = config.port || 6000;
	return new Promise<Socket>((resolve, reject) => {
		tryConnect(port, 200, 25, resolve, reject);
	});
}

function getFirefoxExecutablePath(config: LaunchConfiguration): string {

	if (config.firefoxExecutable) {
		return config.firefoxExecutable;
	}
	
	let candidates: string[] = [];
	switch (os.platform()) {
		
		case 'linux':
		case 'freebsd':
		case 'sunos':
			candidates = [
				'/usr/bin/firefox'
			]
			break;
<commit_msg>return an error message if the firefox executable can't be found<commit_after>import * as os from 'os';
import * as path from 'path';
import { accessSync, X_OK } from 'fs';
import { connect, Socket } from 'net';
import { spawn, ChildProcess } from 'child_process';
import { LaunchConfiguration } from '../adapter/launchConfiguration';

export function launchFirefox(config: LaunchConfiguration, 
	convertPathToFirefoxUrl: (path: string) => string): ChildProcess | string {

	let firefoxPath = getFirefoxExecutablePath(config);	
	if (!firefoxPath) {
		let errorMsg = 'Couldn\'t find the Firefox executable. ';
		if (config.firefoxExecutable) {
			errorMsg += 'Please correct the path given in your launch configuration.'
		} else {
			errorMsg += 'Please specify the path in your launch configuration.'
		}
		return errorMsg;
	}
	
	let port = config.port || 6000;
	let firefoxArgs: string[] = [ '-start-debugger-server', String(port), '-no-remote' ];
	if (config.profile) {
		firefoxArgs.push('-P', config.profile);
	}
	if (Array.isArray(config.firefoxArgs)) {
		firefoxArgs = firefoxArgs.concat(config.firefoxArgs);
	}
	if (config.file) {
		if (!path.isAbsolute(config.file)) {
			return 'The "file" property in the launch configuration has to be an absolute path';
		}
		firefoxArgs.push(convertPathToFirefoxUrl(config.file));
	} else if (config.url) {
		firefoxArgs.push(config.url);
	} else {
		return 'You need to set either "file" or "url" in the launch configuration';
	}
	
	let childProc = spawn(firefoxPath, firefoxArgs, { detached: true, stdio: 'ignore' });
	childProc.unref();
	return childProc;
}

export function waitForSocket(config: LaunchConfiguration): Promise<Socket> {
	let port = config.port || 6000;
	return new Promise<Socket>((resolve, reject) => {
		tryConnect(port, 200, 25, resolve, reject);
	});
}

function getFirefoxExecutablePath(config: LaunchConfiguration): string {

	if (config.firefoxExecutable) {
		if (isExecutable(config.firefoxExecutable)) {
			return config.firefoxExecutable;
		} else {
			return null;
		}
	}
	
	let candidates: string[] = [];
	switch (os.platform()) {
		
		case 'linux':
		case 'freebsd':
		case 'sunos':
			candidates = [
				'/usr/bin/firefox'
			]
			break;

{'fraction_non_alphanumeric': 0.13351634639381083, 'fraction_numerical': 0.006488644871474919, 'mean_word_length': 4.558945908460472, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '471672', 'n_tokens_mistral': 1386, 'n_tokens_neox': 1249, 'n_words': 344}