# frozen_string_literal: true

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

require "async/service/generic"
require_relative "../server"

module Async
	module HTTY
		module Service
			# An async-service managed service that runs an HTTY server.
			# Mirrors Falcon::Service::Server but binds to stdin/stdout instead
			# of a TCP endpoint. The container thread lifetime equals the HTTY session.
			#
			# We use Generic rather than Managed::Service because Managed::Service
			# calls instance.ready! *after* run() returns. For HTTY, run() blocks for
			# the entire session, so ready! would never be signalled while the session
			# is live — causing the container controller to hang in wait_until_ready.
			class Server < Async::Service::Generic
				# Set up the container to run the HTTY server.
				# Signals instance.ready! before the blocking accept loop so the
				# controller does not stall waiting for startup confirmation.
				#
				# @parameter container [Async::Container::Generic]
				def setup(container)
					super
					
					container.run(**@evaluator.container_options) do |instance|
						Sync do
							server = Async::HTTY::Server.new(@evaluator.middleware)
							
							original_input = $stdin.dup
							original_output = $stdout.dup
							original_error = $stderr.dup
							
							stream = ::Protocol::HTTY::Stream.new(original_input, original_output)
							
							$stdin.reopen(File::NULL)
							$stdout.reopen(File::NULL)
							if path = ENV.fetch("HTTY_ERROR_LOG", nil)
								$stderr.reopen(File.open(path, "a"))
							else
								$stderr.reopen(File::NULL)
							end
							
							instance.ready!
							
							Async::HTTY::Server.with_raw_terminal(original_input) do
								server.accept(stream)
							end
						ensure
							$stdin.reopen(original_input) rescue nil
							$stdout.reopen(original_output) rescue nil
							$stderr.reopen(original_error) rescue nil
						end
					end
				end
			end
		end
	end
end
