/**
 * OS Compatibility Utility
 * Cross-platform compatibility helpers untuk AlmaLinux dan Windows
 */

const os = require('os');
const path = require('path');
const fs = require('fs');

/**
 * Get OS platform information
 * @returns {Object} Platform information
 */
function getPlatformInfo() {
	const platform = os.platform();
	const isWindows = platform === 'win32';
	const isLinux = platform === 'linux';
	const isDarwin = platform === 'darwin';
	const isAlmaLinux = isLinux && (os.release().includes('el') || os.release().includes('almalinux') || process.env.OS_RELEASE?.includes('almalinux'));
	
	return {
		platform,
		isWindows,
		isLinux,
		isDarwin,
		isAlmaLinux,
		release: os.release(),
		arch: os.arch(),
	};
}

/**
 * Find executable in common paths (cross-platform)
 * @param {string} executableName - Name of executable (e.g., 'wkhtmltopdf')
 * @param {Object} options - Options
 * @returns {string|null} Full path to executable or null if not found
 */
function findExecutable(executableName, options = {}) {
	const platformInfo = getPlatformInfo();
	const customPaths = options.customPaths || [];
	
	// Common paths per platform
	let searchPaths = [];
	
	if (platformInfo.isWindows) {
		// Windows common paths
		searchPaths = [
			path.join(process.env.ProgramFiles || 'C:\\Program Files', executableName, 'bin', `${executableName}.exe`),
			path.join(process.env['ProgramFiles(x86)'] || 'C:\\Program Files (x86)', executableName, 'bin', `${executableName}.exe`),
			path.join(process.env.LOCALAPPDATA || '', executableName, 'bin', `${executableName}.exe`),
			`C:\\${executableName}\\bin\\${executableName}.exe`,
		];
	} else {
		// Linux/Unix common paths
		searchPaths = [
			`/usr/local/bin/${executableName}`,
			`/usr/bin/${executableName}`,
			`/bin/${executableName}`,
			`/opt/${executableName}/bin/${executableName}`,
			path.join(os.homedir(), 'bin', executableName),
			path.join(os.homedir(), '.local', 'bin', executableName),
		];
	}
	
	// Add custom paths
	searchPaths = [...customPaths, ...searchPaths];
	
	// Search for executable
	for (const execPath of searchPaths) {
		try {
			if (fs.existsSync(execPath)) {
				// Check if it's executable (on Unix)
				if (platformInfo.isWindows || fs.accessSync(execPath, fs.constants.X_OK) === undefined) {
					return execPath;
				}
			}
		} catch (err) {
			// Continue searching
			continue;
		}
	}
	
	// Try PATH environment variable
	try {
		const { execSync } = require('child_process');
		const whichCmd = platformInfo.isWindows ? 'where' : 'which';
		const result = execSync(`${whichCmd} ${executableName}`, { encoding: 'utf8', stdio: ['pipe', 'pipe', 'ignore'] });
		const foundPath = result.trim().split('\n')[0];
		if (foundPath && fs.existsSync(foundPath)) {
			return foundPath;
		}
	} catch (err) {
		// Not found in PATH
	}
	
	return null;
}

/**
 * Get wkhtmltopdf path (cross-platform)
 * @param {Object} options - Options
 * @returns {string} Path to wkhtmltopdf executable
 */
function getWkhtmltopdfPath(options = {}) {
	const platformInfo = getPlatformInfo();
	
	// Try to find executable
	const foundPath = findExecutable('wkhtmltopdf', {
		customPaths: options.customPaths || [],
	});
	
	if (foundPath) {
		return foundPath;
	}
	
	// Fallback to default paths
	if (platformInfo.isWindows) {
		return options.defaultWindowsPath || 'C:\\Program Files\\wkhtmltopdf\\bin\\wkhtmltopdf.exe';
	} else {
		return options.defaultUnixPath || '/usr/local/bin/wkhtmltopdf';
	}
}

/**
 * Ensure directory exists (cross-platform)
 * @param {string} dirPath - Directory path
 * @param {Object} options - Options
 * @returns {boolean} True if directory exists or was created
 */
function ensureDirectory(dirPath, options = {}) {
	try {
		if (!fs.existsSync(dirPath)) {
			fs.mkdirSync(dirPath, { recursive: true, mode: options.mode || 0o755 });
		}
		return true;
	} catch (error) {
		console.error(`[OSCompatibility] Failed to ensure directory: ${dirPath}`, error.message);
		return false;
	}
}

/**
 * Get temp directory (cross-platform)
 * @returns {string} Temp directory path
 */
function getTempDir() {
	return os.tmpdir();
}

/**
 * Normalize path for current platform
 * @param {string} filePath - File path
 * @returns {string} Normalized path
 */
function normalizePath(filePath) {
	return path.normalize(filePath);
}

/**
 * Check if path is absolute
 * @param {string} filePath - File path
 * @returns {boolean} True if absolute
 */
function isAbsolutePath(filePath) {
	return path.isAbsolute(filePath);
}

/**
 * Join paths (cross-platform)
 * @param {...string} paths - Path segments
 * @returns {string} Joined path
 */
function joinPaths(...paths) {
	return path.join(...paths);
}

/**
 * Resolve path (cross-platform)
 * @param {...string} paths - Path segments
 * @returns {string} Resolved absolute path
 */
function resolvePath(...paths) {
	return path.resolve(...paths);
}

/**
 * Get file separator for current platform
 * @returns {string} Path separator
 */
function getPathSeparator() {
	return path.sep;
}

/**
 * Check if running on production-like environment
 * @returns {boolean} True if production-like
 */
function isProductionLike() {
	const env = process.env.NODE_ENV || '';
	const platformInfo = getPlatformInfo();
	
	// Production-like if:
	// - NODE_ENV is production
	// - Running on Linux (likely server)
	// - Not on Windows (development)
	return env.toLowerCase() === 'production' || (platformInfo.isLinux && !platformInfo.isWindows);
}

module.exports = {
	getPlatformInfo,
	findExecutable,
	getWkhtmltopdfPath,
	ensureDirectory,
	getTempDir,
	normalizePath,
	isAbsolutePath,
	joinPaths,
	resolvePath,
	getPathSeparator,
	isProductionLike,
};
