# frozen_string_literal: true

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

require "build/files/state"

module Build
	module Files
		module Monitor
			# Represents a tracked set of files with an associated callback.
			# 
			# A handle is created when you call {Polling#track_changes} and connects a set of files to a callback block that fires when changes are detected. The handle maintains the state of monitored files and can be removed from the monitor when no longer needed.
			class Handle
				# Initialize a new handle.
				# 
				# @parameter monitor [Polling] The monitor that owns this handle.
				# @parameter files [List] The list of files to track.
				# @parameter block [Proc] The callback to invoke when changes are detected.
				def initialize(monitor, files, &block)
					@monitor = monitor
					@state = State.new(files)
					@block = block
				end
				
				# @attribute [Polling] The monitor that owns this handle.
				attr :monitor
				
				# Update the internal state of tracked files.
				# 
				# This method forces an update of the file state without invoking the callback.
				def commit!
					@state.update!
				end
				
				# @returns [Array(Path)] The root directories being monitored by this handle.
				def directories
					@state.files.roots
				end
				
				# Remove this handle from the monitor.
				# 
				# After calling this method, the callback will no longer be invoked when changes are detected.
				def remove!
					@monitor.delete(self)
				end
				
				# Inform the handle that it might have been modified.
				def changed!
					# If @state.update! did not find any changes, don't invoke the callback:
					if @state.update!
						@block.call(@state)
					end
				end
				
				# @returns [String] A string representation of the handle.
				def to_s
					"\#<#{self.class} @state=#{@state} @block=#{@block}>"
				end
			end
		end
	end
end
