require "rover"
require "rover_utils"
require "relay_board"

#all methods in this class that begin with the word "test"
#will be tested when the run method is called. All "test"
#methods should return a true/false value indicating success
#or failure.
class PrediveTest
  include LogHelper

  def run
    puts "Beginning rover pre-dive test."
    @rover = Rover.instance
    methods = self.methods
    testMethods = Array.new
    methods.each {|method| 
      if(method =~ /test.*/)
        testMethods << method
      end
    }
    testMethods.each{|testMethod|
      puts "next method (#{testMethod}). continue? [y/n/s(kip)] y"
      response = gets("\n")
      if(response =~ /n/)
        break
      elsif(response =~ /s/)
        next
      end
      puts "running #{testMethod}"
      begin
        response = self.send(testMethod)
      rescue Exception => e
        puts "caught an exception in test method"
        puts "exception = #{e}"
        response = false
      end
      if(response)
        puts "#{testMethod} succeeded"
      else
        puts "#{testMethod} failed"
      end
    }
    
    @rover.relay.allOff
    puts "all relays turned off"
    puts "Pre-dive testing completed"
  end

  def testMotors
    @rover.relay.motorsOn
    success = true
    puts "setting motor to \"A\""
    @rover.motors.active_motor_num = "A"
    puts "getting motor status"
    sleep(2)
    puts "status: #{@rover.motors.current_status?}"
    sleep(1)
    error = @rover.motors.has_error
    if(error)
      puts "motors have an error: #{@rover.motors.error_message}"
      success = false
    end
    @rover.relay.motorsOff
    success
  end

  def testCurrentMeter
    @rover.relay.v12On
    sleep(1)
    success = true
    @rover.acm.run
    puts "Current meter is collecting data, is data showing up in datalog? [y/n] y"
    response = gets("\n")
    if(response =~ /n/)
      success = false
    end
    @rover.acm.stop_thread
    @rover.relay.v12Off
    success
  end

  def testVideo
    @rover.relay.v12On
    @rover.relay.videoOn
    success = true
    puts "check if video is on by going to webserver and observing it (after 30 secs)"
    puts "is image appearing at http://192.168.0.90 ? [y/n] y"
    response = gets("\n")
    if(response =~ /n/)
      success = false
    end
    @rover.relay.v12Off
    success
  end

  def testOptodes
    @rover.relay.v12On
    @rover.relay.optodeOn
    success = true
    chamber_optode = Aanderaa.new nil    
    ref_optode = Aanderaa.new nil
    response = chamber_optode.acquire_data
    if(response)
      puts "chamber optode data: #{chamber_optode.rawdata}"
    else
      puts "chamber optode returned false from acquire_data"
      success = false
    end
    response = ref_optode.acquire_data
    if(response)
      puts "reference optode data: #{ref_optode.rawdata}"
    else
      puts "reference optode returned false from acquire_data"
      success = false
    end
    @rover.relay.optodeOff
    @rover.relay.v12Off
    success
  end

  def testValvePump
    @rover.relay.v12On
    @rover.relay.pumpOn
    success = true
    puts "is valve pump working? [y/n] y"
    response = STDIN.gets("\n")
    if(response =~ /n/)
      success = false
    end
    @rover.relay.pumpOff
    @rover.relay.v12Off
    success
  end

  def testStirMotor
    @rover.relay.v5On
    success = true
    puts "is stir motor working? [y/n] y"
    response = STDIN.gets("\n")
    if(response =~ /n/)
      success = false
    end
    @rover.relay.v5Off
    success
  end
  
  def testRack
    success = true
    @rover.relay.rackOn
    sleep(2)
    @rover.rack.reinit()
    sleep(2)
    puts "getting racks encoder position"
    puts "Rack encoder position = #{@rover.rack.encoder_position}" 
    puts "send rack home? [y/n] n"
    response = STDIN.gets("\n")
    if(response =~ /y/)
      @rover.rack.home
      puts "did rack go home? [y/n] y"
      response = STDIN.gets("\n")
      if(response =~ /n/)
        success = false
      end
      puts "insert chamber? [y/n] n"
      response = STDIN.gets("\n")
      if(response =~ /y/)
        @rover.rack.insert_chamber
        puts "did rack insert? [y/n] y"
        response = STDIN.gets("\n")
        if(response =~ /n/)
          success = false
        end
        puts "send rack home? [y/n] y"
        response = STDIN.gets("\n")
        unless(response =~ /n/)
          @rover.rack.home
        end
      end
    end
    success
  end
    
  def testRelay
    success = true
    relay = @rover.relay
    relays = [["Rack", RelayBoard::RACK], ["Optode", RelayBoard::OPTODE],
              ["Pump", RelayBoard::PUMP], ["v5", RelayBoard::V5],
              ["v12", RelayBoard::V12], ["Video", RelayBoard::VIDEO],
              ["Motors", RelayBoard::MOTORS]]
    relays.each {|r|
      puts "testing #{r[0]} relay"
      relay.turn_on r[1]
      response = relay.get_status r[1]
      if(response.to_i != 1)
        success = false
        puts "#{r[0]} relay did not turn on"
      else
        relay.turn_off r[1]
        response = relay.get_status r[1]
        if(response.to_i != 0)
          success = false
          puts "#{r[0]} relay did not turn off"
        end
      end
    }
    
    relay.allOff
    response = relay.get_status 0
    if(!response =~ /00/)
      success = false
      puts "relay did not turn all off after relay.allOff command"
    end
    success
  end
end

pre = PrediveTest.new()
pre.run()