# frozen_string_literal: true

# Released under the MIT License.
# Copyright, 2023-2026, by Samuel Williams.

require_relative "generic"
require_relative "process_group"

module Async
	module WebDriver
		module Bridge
			# A bridge to the Firefox browser using `geckodriver`.
			#
			# ``` ruby
			# begin
			# 	bridge = Async::WebDriver::Bridge::Firefox.start
			# 	client = Async::WebDriver::Client.open(bridge.endpoint)
			# ensure
			# 	bridge&.close
			# end
			class Firefox < Generic
				# @returns [String] The path to the `geckodriver` executable.
				def driver_path
					@options.fetch(:driver_path, "geckodriver")
				end
				
				# @returns [String] The version of the `geckodriver` executable.
				def version
					::IO.popen([self.driver_path, "--version"]) do |io|
						return io.read
					end
				rescue Errno::ENOENT
					return nil
				end
				
				# A locally managed `geckodriver` process.
				class Driver < Bridge::Driver
					# Initialize a managed Firefox driver process.
					# @parameter options [Hash] Driver configuration options.
					def initialize(**options)
						super(**options)
						@process_group = nil
					end
					
					# @returns [Integer] Firefox drivers support one session at a time.
					def concurrency
						1
					end
					
					# @returns [Array(String)] The arguments to pass to the `geckodriver` executable.
					def arguments(**options)
						[
							options.fetch(:driver_path, "geckodriver"),
							"--port", self.port.to_s,
						].compact
					end
					
					# Start the managed Firefox driver process and wait for readiness.
					def start
						@process_group = ProcessGroup.spawn(*arguments(**@options))
						
						super
					end
					
					# Stop the managed Firefox driver process.
					def close
						if @process_group
							@process_group.close
							@process_group = nil
						end
						
						super
					end
				end
				
				# Start the driver.
				def start(**options)
					Driver.new(**@options, **options).tap(&:start)
				end
				
				# The default capabilities for the Firefox browser which need to be provided when requesting a new session.
				# @parameter headless [Boolean] Whether to run the browser in headless mode.
				# @returns [Hash] The default capabilities for the Firefox browser.
				def default_capabilities(headless: self.headless?)
					{
						alwaysMatch: {
							browserName: "firefox",
							"moz:firefoxOptions": {
								args: [headless ? "-headless" : nil].compact,
							}
						}
					}
				end
			end
		end
	end
end
