class Build::Files::State

def empty?

def empty?
	@files.to_a.empty?
end

def initialize(files)

def initialize(files)
	raise ArgumentError.new("Invalid files list: #{files}") unless Files::List === files

	@files = files
	@times = {}

	update!
end

def inspect

def inspect
	"<State Added:#{@added} Removed:#{@removed} Changed:#{@changed} Missing:#{@missing}>"
end

def intersects?(outputs)

Outputs is a list of full paths and must not include any patterns/globs.
def intersects?(outputs)
	@files.intersects?(outputs)
end

def missing?

def missing?
	!@missing.empty?
end

def update!

def update!
	last_times = @times
	@times = {}

	@added = []
	@removed = []
	@changed = []
	@missing = []

	file_times = []
	
	@files.each do |path|
		# When processing the same path twice (perhaps by accident), we should skip it otherwise it might cause issues when being deleted from last_times multuple times.
		next if @times.include? path
		
		if File.exist?(path)
			modified_time = File.mtime(path)
		
			if last_time = last_times.delete(path)
				# Path was valid last update:
				if modified_time != last_time
					@changed << path
					
					# puts "Changed: #{path}"
				end
			else
				# Path didn't exist before:
				@added << path
				
				# puts "Added: #{path}"
			end
		
			@times[path] = modified_time
		
			unless File.directory?(path)
				file_times << FileTime.new(path, modified_time)
			end
		else
			@missing << path
			
			# puts "Missing: #{path}"
		end
	end
	
	@removed = last_times.keys
	# puts "Removed: #{@removed.inspect}" if @removed.size > 0
	
	@oldest_time = file_times.min
	@newest_time = file_times.max
	
	return @added.size > 0 || @changed.size > 0 || @removed.size > 0 || @missing.size > 0
end