# frozen_string_literal: true

# Released under the MIT License.
# Copyright, 2021-2025, by Samuel Williams.

require_relative "polling"
require "io/watch"

module Build
	module Files
		module Monitor
			# A platform-specific filesystem monitor using native OS APIs.
			# 
			# This implementation uses platform-specific APIs (FSEvent on macOS, INotify on Linux) for efficient, event-driven file monitoring. It extends {Polling} but replaces the polling mechanism with native filesystem events.
			class Native < Polling
				# Run the monitor using native filesystem events.
				# 
				# This method blocks until interrupted via `throw :interrupt`. Unlike {Polling#run}, this uses native OS events rather than polling.
				# 
				# @yields After each filesystem event.
				def run(**options, &block)
					catch(:interrupt) do
						while true
							run_roots(self.roots, **options, &block)
						end
					end
				end
				
				# Monitor the specified roots for changes using native events.
				# 
				# @parameter roots [Array(String)] The root directories to monitor.
				# @yields {...} After each filesystem event.
				# @returns [Boolean] True if the set of monitored directories was updated.
				def run_roots(roots, **options, &block)
					monitor = IO::Watch::Monitor.new(self.roots, **options)
					
					monitor.run do |event|
						if root = event[:root]
							self.update([root])
							
							yield if block_given?
							
							if self.updated
								return true
							end
						end
					end
					
					return false
				end
			end
		end
	end
end
