require 'custodian/settings'
require 'custodian/testfactory'

require 'uri'


#
#  The open-proxy test.
#
#  This object is instantiated if the parser sees a line such as:
#
###
### foo.vm.bytemark.co.uk must not run openproxy otherwise 'insecurity'.
###
#
#
module Custodian

  module ProtocolTest


    class OpenProxyTest < TestFactory

      #
      # The line from which we were constructed.
      #
      attr_reader :line


      #
      # Constructor
      #
      def initialize(line)

        #
        #  Save the line
        #
        @line = line

        #
        #  Save the target
        #
        @host = line.split(/\s+/)[0]

      end


      #
      # Allow this test to be serialized.
      #
      def to_s
        @line
      end



      #
      # Run the test.
      #
      def run_test

        #  Reset state, in case we've previously run.
        @error    = nil

        begin
          require 'rubygems'
          require 'curb'
        rescue LoadError
          @error = "The required rubygem 'curb' was not found."
          return false
        end

        #
        # Get the timeout period for this test.
        #
        settings = Custodian::Settings.instance
        period   = settings.timeout

        begin
          timeout(period) do
            begin
              c = Curl::Easy.new
              c.follow_location = true
              c.max_redirects   = 10
              c.ssl_verify_host = false
              c.proxy_url       = @host
              c.proxy_tunnel    = true
              c.url             = 'http://google.com/'
              c.ssl_verify_peer = false
              c.timeout         = period
              c.perform
              @status = c.response_code
              @content = c.body_str
            rescue Curl::Err::SSLCACertificateError => x
              @error = 'SSL-Validation error'
              return false
            rescue Curl::Err::TimeoutError
              @error = 'Timed out fetching page.'
              return false
            rescue Curl::Err::TooManyRedirectsError
              @error = 'Too many redirections (more than 10)'
              return false
            rescue => x
               @error = "Exception: #{x}"
              return false
            end
          end
        rescue Timeout::Error => _e
          @error = 'Timed out during fetch.'
          return Custodian::TestResult::TEST_FAILED
        end

        #
        # A this point we've either had an exception, or we've
        # got a result.
        #
        if (@status.to_i == 200)
          return Custodian::TestResult::TEST_PASSED
        else
          @error = "Proxy fetch of http://google.com/ via #{@host} failed"
          return Custodian::TestResult::TEST_FAILED
        end
      end



      #
      # If the test fails then report the error.
      #
      def error
        @error
      end




      register_test_type 'openproxy'



    end
  end
end