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

require "date"

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

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

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

			@results		= []

			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_fetch_process_sleep_cycle()
		end

		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_fetch_process_sleep_cycle
			while true
				current_time = DateTime.now()
				@running_mods.each do |mod|
					save_results(mod, current_time, mod.results())
					notify() if mod.notify?
				end
				make_output()
				sleep @config[:repeat]
			end
		end

		def save_results(mod, time, result)
			mod_results = @results[mod]

			if mod_results.size >= @config[:history_size]
				mod_results.slice!(@config[:history_size], @results[mod].size)
			end

			#shift() and push() operations have O(1) complexity.
			mod_results.shift()
			mod_results.push([time: time, value: result])
		end

		def notify

		end

		def make_output

		end
	end
end