require 'httparty'
require 'json'

module Cloud66
  module Utils

    class Server
      include HTTParty
      # set the default request timeout to 45 seconds
      # this sets the open_timeout and the read_timeout
      default_timeout 45

      def self.send_configure(data)
        process(do_request(:post, '/server/configure.json', build_content(data)))
      end

      def self.send_pulse
        process(do_request(:get, "/server/#{$config.agent_uid}/pulse.json", build_content))
      end

      def self.send_address(data)
        process(do_request(:post, "/server/#{$config.agent_uid}/address.json", build_content(data)))
      end

      def self.send_vitals(data)
        process(do_request(:post, "/server/#{$config.agent_uid}/vitals_alerts.json", build_content(data)))
      end

      def self.send_job_start(job_uid)
        process(do_request(:get, "/job/#{job_uid}/start.json", build_content))
      end

      def self.send_job_end(job_uid, data)
        process(do_request(:post, "/job/#{job_uid}/end.json", build_content(data)))
      end

      def self.send_fail2ban(data)
        process(do_request(:post, "/server/#{$config.agent_uid}/fail2ban.json", build_content(data)))
      end

      def self.send_message(data)
        #puts data
        process(do_request(:post, "/server/#{$config.agent_uid}/message.json", build_content(data)))
      end

      private

      def self.process(response)
        $logger.debug "Received response!"
        if response.code != 200
          $logger.debug "Response code: #{response.code}"
          $logger.debug "Response body: #{response.body}"
          raise response.body
        else
          parsed_response = response.parsed_response
          unless parsed_response['ok']
            if parsed_response['shut_down']
              $config.disabled = true
              $config.save
              exit 86
            elsif parsed_response.has_key?('error')
              raise parsed_response['error']
            else
              raise "unidentified error"
            end
          end
          $logger.debug "Parsed response: #{parsed_response}"
          parsed_response['data']
        end
      end

      def self.do_request(verb, url, content)
        $logger.debug "Sending (#{verb}) request..."
        $logger.debug "Request url: #{url}"
        $logger.debug "Request content: #{content}"
        base_uri $config.api_url
        self.send verb, url, content
      end

      def self.build_content(data = nil)
        time = Time.now.utc.to_i
        hash = Digest::SHA1.hexdigest("#{$config.api_key}#{$config.secret_key}#{time}").downcase
        if data.nil?
          content = {:headers => {'api-key' => $config.api_key, 'hash' => hash, 'time' => time.to_s}}
        else
          content = {:headers => {'api-key' => $config.api_key, 'hash' => hash, 'time' => time.to_s, 'Content-Type' => 'application/json'}, :body => {data: data}.to_json}
        end
        content
      end

    end
  end
end