require 'timeout'

module Net # :nodoc:
  module DNS
    class Resolver
      class DnsTimeout
        attr_reader :seconds

        def initialize(seconds)
          if seconds.is_a?(Numeric) && seconds >= 0
            @seconds = seconds
          else
            raise ArgumentError, "Invalid value for tcp timeout"
          end
        end

        # Returns a string representation of the timeout corresponding
        # to the number of <tt>@seconds</tt>.
        def to_s
          @seconds == 0 ? @output.to_s : @seconds.to_s
        end

        def pretty_to_s
          transform(@seconds)
        end

        # Executes the method's block. If the block execution terminates before +sec+
        # seconds has passed, it returns true. If not, it terminates the execution
        # and raises Timeout::Error.
        # If @seconds is 0 or nil, no timeout is set.
        def timeout(&block)
          raise LocalJumpError, "no block given" unless block_given?

          Timeout.timeout(@seconds, &block)
        end

        private

        def transform(secs)
          case secs
          when 0
            to_s
          when 1..59
            "#{secs} seconds"
          when 60..3559
            "#{secs / 60} minutes and #{secs % 60} seconds"
          else
            hours = secs / 3600
            secs -= (hours * 3600)
            "#{hours} hours, #{secs / 60} minutes and #{secs % 60} seconds"
          end
        end
      end

      class TcpTimeout < DnsTimeout
        def initialize(seconds)
          @output = "infinite"
          super
        end
      end

      class UdpTimeout < DnsTimeout
        def initialize(seconds)
          @output = "not defined"
          super
        end
      end
    end
  end
end
