<commit_before>
module Plezi

	module_function

	# Defines methods used to set up the Plezi app.

	# public API to add a service to the framework.
	# accepts a Hash object with any of the following options (Hash keys):
	# port:: port number. defaults to 3000 or the port specified when the script was called.
	# host:: the host name. defaults to any host not explicitly defined (a catch-all). NOTICE: in order to allow for hostname aliases, this is host emulation and the listening socket will bind to all the addresses available. To limit the actual binding use the `:bind` parameter as set by the GReactor's API - in which case host aliases might not work.
	# alias:: a String or an Array of Strings which represent alternative host names (i.e. `alias: ["admin.google.com", "admin.gmail.com"]`).
	# public:: the public root folder. if this is defined, static files will be served from this folder and all it's sub-folders. Plezi does NOT support file indexing.
	# assets:: the assets root folder. defaults to nil (no assets support). if the path is defined, assets will be served from `/assets/...` (or the public_asset path defined) before any static files. assets will not be served if the file in the /public/assets folder if up to date (a rendering attempt will be made for systems that allow file writing).
	# assets_public:: the assets public uri location (uri format, NOT a file path). defaults to `/assets`. `save_assets` will set if assets should be saved to the assets public folder as static files (defaults to false).
	# assets_callback:: a method that accepts two parameters: (request, response) and renders any custom assets. the method should return `false` unless it had set the response.
	# save_assets:: saves the rendered assets to the filesystem, under the public folder. defaults to false.
	# templates:: the templates root folder. defaults to nil (no template support). templates can be rendered by a Controller class, using the `render` method.
	# ssl:: if true, an SSL service will be attempted. if no certificate is defined, an attempt will be made to create a self signed certificate.
	# ssl_key:: the public key for the SSL service.
	# ssl_cert:: the certificate for the SSL service.
	#
	# Assets:
	#
	# Assets support will render `.sass`, `.scss` and `.coffee` and save them as local files (`.css`, `.css`, and `.js` respectively)
	# before sending them as static files.
	#
	# Should you need to render a different type of asset, you can define an assets_callback (or submit a pull request with a patch). 
	# 
	# templates:
	#
	# Plezi's controller.render ERB, Slim and Haml are natively supported.
	#
	# @return [Plezi::Router]
	#
	def listen parameters = {}
		# update default values
		parameters[:index_file] ||= 'index.html'
		parameters[:assets_public] ||= '/assets'
		parameters[:assets_public].chomp! '/'
		parameters[:public] ||= parameters[:root] # backwards compatability
		puts "Warning: 'root' option is being depracated. use 'public' instead." if parameters[:root]

		# check if the port is used twice.
		@routers_locker.synchronize do
			@active_router = GRHttp.listen(parameters)
			unless @active_router[:upgrade_handler]
				@routers << (@active_router[:http_handler] = ::Plezi::Base::HTTPRouter.new)
				@active_router[:upgrade_handler] = @active_router[:http_handler].upgrade_proc
			else
				@active_router.delete :alias
			end
			@active_router[:http_handler].add_host(parameters[:host], @active_router.merge(parameters) )
			@active_router = @active_router[:http_handler]
		end
		# return the current handler or the protocol..
		@active_router
	end

	# clears all the listeners and routes defined
	def clear_app
		@routers_locker.synchronize {GReactor.clear_listeners; @routers.clear}
	end
	# adds a route to the last server created
	def route(path, controller = nil, &block)
		raise "Must define a listener before adding a route - use `Plezi.listen`." unless @active_router
		@routers_locker.synchronize { @active_router.add_route path, controller, &block }
	end


	# adds a shared route to all existing services and hosts.
	def shared_route(path, controller = nil, &block)
		raise "Must have created at least one Pleze service before calling `shared_route` - use `Plezi.listen`." unless @routers
		@routers_locker.synchronize { @routers.each {|r| r.add_shared_route path, controller, &block } }
	end

	# adds a host to the last server created
	#
	# accepts a host name and a parameter(s) Hash which are the same parameter(s) as {Plezi.listen} accepts:
	def host(host_name, params)
		raise "Must define a listener before adding a route - use `Plezi.listen`." unless @active_router
		@routers_locker.synchronize { @active_router.add_host host_name, params }
	end

	# starts the Plezi framework server and hangs until the exit signal is given.
	def start
		start_async
		puts "\nPress ^C to exit.\n"
		GReactor.join { puts "\r\nStarting shutdown sequesnce. Press ^C to force quit."}
	end

	# Makes sure the GRHttp server will be used by Rack (if Rack is available) and disables Plezi's autostart feature.
	#
	# This method is a both a fail safe and a shortcut. Plezi will automatically attempt to diable autostart when discovering Rack
	# but this method also makes sure that the GRHttp is set as the Rack server by setting the ENV\["RACK_HANDLER"] variable.
	#
	# This is used as an alternative to {Plezi.start_placebo}.
	#
	# Use {Plezi.start_placebo} to augment an existing app while operating Plezi on a different process or server.
	#
	# Use {Plezi.start_rack} to augment an existing Rack app (i.e. Rails/Sinatra) by loading both Plezi and the existing Rack app
	# to the GRHtto server (it will set up GRHttp as the Rack server).
	def start_rack
		Object.const_set("NO_PLEZI_AUTO_START", true) unless defined?(NO_PLEZI_AUTO_START)
		ENV["RACK_HANDLER"] = 'grhttp'
	end
	# starts the Plezi framework and returns immidiately,
	# allowing you to run the Plezi framework along side another framework. 
	def start_async
		Object.const_set("NO_PLEZI_AUTO_START", true) unless defined?(NO_PLEZI_AUTO_START)
		return GReactor.start if GReactor.running?
		puts "Starting Plezi #{Plezi::VERSION} Services using the GRHttp #{GRHttp::VERSION} server."
		GReactor.on_shutdown { puts "Plezi shutdown. It was fun to serve you."  }
		GReactor.start Plezi::Settings.max_threads
	end
	# This allows you to run the Plezi framework along side another framework - WITHOUT running the actual server.
	#
	# The server will not be initiatet and instead you will be able to use Plezi controllers and the Redis auto-config
	# to broadcast Plezi messages to other Plezi processes - allowing for scalable intigration of Plezi into other frameworks.
	def start_placebo
		GReactor.clear_listeners
		redis # make sure the redis connection is activated
		puts "* Plezi #{Plezi::VERSION} Services will start with no Server...\n"
		start_async
	end

	# this module contains the methods that are used as a DSL and sets up easy access to the Plezi framework.
	#
	# use the`listen`, `host` and `route` functions rather then accessing this object.
	#
	@active_router = nil
	@routers_locker = Mutex.new
	@routers ||= [].to_set
end

Encoding.default_internal = 'utf-8'
Encoding.default_external = 'utf-8'

NO_PLEZI_AUTO_START = true if defined?(::Rack::Builder)<commit_msg>better info line<commit_after>
module Plezi

	module_function

	# Defines methods used to set up the Plezi app.

	# public API to add a service to the framework.
	# accepts a Hash object with any of the following options (Hash keys):
	# port:: port number. defaults to 3000 or the port specified when the script was called.
	# host:: the host name. defaults to any host not explicitly defined (a catch-all). NOTICE: in order to allow for hostname aliases, this is host emulation and the listening socket will bind to all the addresses available. To limit the actual binding use the `:bind` parameter as set by the GReactor's API - in which case host aliases might not work.
	# alias:: a String or an Array of Strings which represent alternative host names (i.e. `alias: ["admin.google.com", "admin.gmail.com"]`).
	# public:: the public root folder. if this is defined, static files will be served from this folder and all it's sub-folders. Plezi does NOT support file indexing.
	# assets:: the assets root folder. defaults to nil (no assets support). if the path is defined, assets will be served from `/assets/...` (or the public_asset path defined) before any static files. assets will not be served if the file in the /public/assets folder if up to date (a rendering attempt will be made for systems that allow file writing).
	# assets_public:: the assets public uri location (uri format, NOT a file path). defaults to `/assets`. `save_assets` will set if assets should be saved to the assets public folder as static files (defaults to false).
	# assets_callback:: a method that accepts two parameters: (request, response) and renders any custom assets. the method should return `false` unless it had set the response.
	# save_assets:: saves the rendered assets to the filesystem, under the public folder. defaults to false.
	# templates:: the templates root folder. defaults to nil (no template support). templates can be rendered by a Controller class, using the `render` method.
	# ssl:: if true, an SSL service will be attempted. if no certificate is defined, an attempt will be made to create a self signed certificate.
	# ssl_key:: the public key for the SSL service.
	# ssl_cert:: the certificate for the SSL service.
	#
	# Assets:
	#
	# Assets support will render `.sass`, `.scss` and `.coffee` and save them as local files (`.css`, `.css`, and `.js` respectively)
	# before sending them as static files.
	#
	# Should you need to render a different type of asset, you can define an assets_callback (or submit a pull request with a patch). 
	# 
	# templates:
	#
	# Plezi's controller.render ERB, Slim and Haml are natively supported.
	#
	# @return [Plezi::Router]
	#
	def listen parameters = {}
		# update default values
		parameters[:index_file] ||= 'index.html'
		parameters[:assets_public] ||= '/assets'
		parameters[:assets_public].chomp! '/'
		parameters[:public] ||= parameters[:root] # backwards compatability
		puts "Warning: 'root' option is being depracated. use 'public' instead." if parameters[:root]

		# check if the port is used twice.
		@routers_locker.synchronize do
			@active_router = GRHttp.listen(parameters)
			unless @active_router[:upgrade_handler]
				@routers << (@active_router[:http_handler] = ::Plezi::Base::HTTPRouter.new)
				@active_router[:upgrade_handler] = @active_router[:http_handler].upgrade_proc
			else
				@active_router.delete :alias
			end
			@active_router[:http_handler].add_host(parameters[:host], @active_router.merge(parameters) )
			@active_router = @active_router[:http_handler]
		end
		# return the current handler or the protocol..
		@active_router
	end

	# clears all the listeners and routes defined
	def clear_app
		@routers_locker.synchronize {GReactor.clear_listeners; @routers.clear}
	end
	# adds a route to the last server created
	def route(path, controller = nil, &block)
		raise "Must define a listener before adding a route - use `Plezi.listen`." unless @active_router
		@routers_locker.synchronize { @active_router.add_route path, controller, &block }
	end


	# adds a shared route to all existing services and hosts.
	def shared_route(path, controller = nil, &block)
		raise "Must have created at least one Pleze service before calling `shared_route` - use `Plezi.listen`." unless @routers
		@routers_locker.synchronize { @routers.each {|r| r.add_shared_route path, controller, &block } }
	end

	# adds a host to the last server created
	#
	# accepts a host name and a parameter(s) Hash which are the same parameter(s) as {Plezi.listen} accepts:
	def host(host_name, params)
		raise "Must define a listener before adding a route - use `Plezi.listen`." unless @active_router
		@routers_locker.synchronize { @active_router.add_host host_name, params }
	end

	# starts the Plezi framework server and hangs until the exit signal is given.
	def start
		start_async
		puts "\nPress ^C to exit.\n"
		GReactor.join { puts "\r\nStarting shutdown sequesnce. Press ^C to force quit."}
	end

	# Makes sure the GRHttp server will be used by Rack (if Rack is available) and disables Plezi's autostart feature.
	#
	# This method is a both a fail safe and a shortcut. Plezi will automatically attempt to diable autostart when discovering Rack
	# but this method also makes sure that the GRHttp is set as the Rack server by setting the ENV\["RACK_HANDLER"] variable.
	#
	# This is used as an alternative to {Plezi.start_placebo}.
	#
	# Use {Plezi.start_placebo} to augment an existing app while operating Plezi on a different process or server.
	#
	# Use {Plezi.start_rack} to augment an existing Rack app (i.e. Rails/Sinatra) by loading both Plezi and the existing Rack app
	# to the GRHtto server (it will set up GRHttp as the Rack server).
	def start_rack
		Object.const_set("NO_PLEZI_AUTO_START", true) unless defined?(NO_PLEZI_AUTO_START)
		ENV["RACK_HANDLER"] = 'grhttp'
	end
	# starts the Plezi framework and returns immidiately,
	# allowing you to run the Plezi framework along side another framework. 
	def start_async
		Object.const_set("NO_PLEZI_AUTO_START", true) unless defined?(NO_PLEZI_AUTO_START)
		return GReactor.start if GReactor.running?
		puts "Starting Plezi #{Plezi::VERSION} Services using GRHttp #{GRHttp::VERSION} and GReactor #{GReactor::VERSION}."
		GReactor.on_shutdown { puts "Plezi shutdown. It was fun to serve you."  }
		GReactor.start Plezi::Settings.max_threads
	end
	# This allows you to run the Plezi framework along side another framework - WITHOUT running the actual server.
	#
	# The server will not be initiatet and instead you will be able to use Plezi controllers and the Redis auto-config
	# to broadcast Plezi messages to other Plezi processes - allowing for scalable intigration of Plezi into other frameworks.
	def start_placebo
		GReactor.clear_listeners
		redis # make sure the redis connection is activated
		puts "* Plezi #{Plezi::VERSION} Services will start with no Server...\n"
		start_async
	end

	# this module contains the methods that are used as a DSL and sets up easy access to the Plezi framework.
	#
	# use the`listen`, `host` and `route` functions rather then accessing this object.
	#
	@active_router = nil
	@routers_locker = Mutex.new
	@routers ||= [].to_set
end

Encoding.default_internal = 'utf-8'
Encoding.default_external = 'utf-8'

NO_PLEZI_AUTO_START = true if defined?(::Rack::Builder)
{'fraction_non_alphanumeric': 0.08168994795946316, 'fraction_numerical': 0.0008216926869350862, 'mean_word_length': 4.3419897585954645, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2063611', 'n_tokens_mistral': 4465, 'n_tokens_neox': 4266, 'n_words': 1864}