require "active_support/core_ext/string/inflections.rb"
require 'nokogiri'
require 'yajl/json_gem'
require 'zabbix'
require "socket"

$:.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
require "zabbix_nudge/jmx"
require "zabbix_nudge/version"


module ZabbixNudge

  def self.root
    @root ="#{File.expand_path('../..',__FILE__)}"
  end

  class Nudge
    def initialize(templates, options = {} )
      options[:zabbix_server_name] = 'localhost' unless options[:zabbix_server_name]
      options[:zabbix_server_port] = '10051' unless options[:zabbix_server_port]
      options[:sender_hostname] = Socket.gethostname unless options[:sender_hostname]

      @options = options
      @templates = template_files(templates)
      @items = template_items(@templates)
    end

    def template_files(templates)
      template_files = []
      template_files = Dir.glob(File.join(templates,'*.xml')) if !templates.is_a?(Array) && File.directory?(templates)
      template_files = templates.map{ |template| template if File.exist?(template) }.compact if templates.is_a?(Array)
      template_files =  [templates] if !templates.is_a?(Array) && File.exist?(templates) && !File.directory?(templates)
      template_files
    end

    def template_items(templates)
      parsed_items = Hash.new

      templates.each do |template|
        template_items = Nokogiri::XML(File.open(template))
        items = template_items.xpath('//item').map {|item| item.attributes['key'].text}.compact
        items.each do |item|
            parts = item.match(/([^\[]+)\[([^\]]+)/)
            unless parts.nil?
              key = parts[1].underscore.to_sym
              attributes = parts[2]
              (parsed_items[key]) ? parsed_items[key] << attributes : parsed_items[key] = [attributes]
            else
              puts "not evaluating: "+item
            end
        end
      end
      parsed_items
    end

    def send(items = :all)

      return if @items.nil?


      nudgers = ( items == :all) ? ( @items.keys.map{ |key| "ZabbixNudge::#{key.to_s.camelize}".constantize }) : ["ZabbixNudge::#{items.camelize}".constantize]

      processed_items = Hash.new

      nudgers.map do |nudger|
        nudger_key = nudger.to_s.demodulize.underscore.to_sym
        processed_items.update nudger.new(@items[nudger_key],@options[nudger_key]).send(:processed_items)
      end

      zbx  = Zabbix::Sender::Buffer.new :host => @options[:zabbix_server_name], :port => @options[:zabbix_server_port]

      processed_items.each do |key,value|
        zbx.append key, value, :host => @options[:sender_hostname]
      end
      zbx.flush

      processed_items
    end
  end

end