require_relative "rubysermon/version"
require_relative "rubysermon/mod_loader"
require_relative "rubysermon/mod_template"
require_relative "rubysermon/configurator"
require_relative "rubysermon/db"
require_relative "rubysermon/output_driver_template"
require_relative "rubysermon/result_grabber"

module Rubysermon
	LIB_PATH = File.expand_path(File.dirname(__FILE__))
	APP_PATH = "#{LIB_PATH}/.."
	MOD_PATH = "#{LIB_PATH}/rubysermon/mod"

	class App

		#todo: refactor
		def initialize
			@config 		= { repeat: 60,
								config_path: "#{LIB_PATH}/rubysermon/config.json",
								db_path: "/tmp/rubysermon_history.db",
								history_size: 90,
								output: "Dummy"
			}

			@running_mods	= []
			@enabled_mods	= []
			@db				= nil

			require "#{LIB_PATH}/rubysermon/output_drivers/#{@config[:output].downcase}"
			@output_driver	= (Rubysermon.const_get(@config[:output])).new

			check_args()
		end

		def run
			read_config()
			enable_and_start_mods()

			if (msg = cannot_start_fetch_process_sleep_cycle?)
				abort(msg)
			end

			#start_db()
			start_result_processor()
		end

		#TODO destructor na ukoncenie threadov

		private

		def check_args
			if not ARGV.empty?
				config_path = ARGV.first
				if File.exists?(config_path)
					@config[:config_path] = config_path
				else
					abort("Wrong config file path. Exiting.")
				end
			end
		end

		def read_config
			configurator = Configurator.new(@config[:config_path])
			config = configurator.get_settings()
			@config.merge!(config)
		end

		def enable_and_start_mods
			@enabled_mods = @config[:modules].to_a
			@enabled_mods.each do |mod| load_mod(mod) end
		end

		def load_mod(mod_name)
			begin
				#prekonvertovat na symbol
				mod = ModLoader.load(mod_name)
				@running_mods.push(mod)
			rescue ModLoaderException => e
				$stderr.puts e.message
			end
		end

		def cannot_start_fetch_process_sleep_cycle?
			if @config[:repeat].to_i < 1
				return "Repeat cycle is too short"
			elsif @running_mods.empty?
				return "There are no enabled modules"
			end

			false
		end

		def start_db
			@db = DB.new(@config[:db_path])
		end

		def start_result_processor
			@result_grabber = ResultGrabber.new(@running_mods, @config[:repeat])
			@result_grabber.run()

			#TODO spravit event machine na pytanie sa, ci netreba poslat notify
			#Kazdy cas interval sa dozadovat grabbera na vysledky.
		end

		def notify

		end

		def make_output
			@results.each do |mod, mod_results|
				@output_driver.log(mod, mod_results)
			end
		end
	end
end