#!/usr/bin/env ruby


require "droiuby"
require 'optparse'
require 'ripper'
require "readline"

$droiuby_host = ENV['DROIUBY_HOST'] || '10.0.2.2'
$device_ip = ENV['DROIUBY_DEVICE'] || nil

options = OptionParser.new do |o|
  o.banner = 
"Usage: drby autostart true|false INSTANCE_NAME [options] # Set specified instance to start on droiuby launch
       drby console [options]                            # Launch an interactive console to the target Android Device running Droiuby
       drby framework update  [FOLDER] [options]         # updates the droiuby framework from folder (default src_framework)
       drby go   [PROJECT_NAME] [options]                # packages an app and uploads to an Android Device running Droiuby
       drby list [options]                               # Lists the app instances running on the phone
       drby live [PROJECT_NAME] [options]                # runs a web instance of the app and tells Droiuby to load it.
       drby new PROJECT_NAME [options]                   # Create a new project 
       drby pack [PROJECT_NAME] [options]                # zips and packages an app
       drby reload                                       # uploads and then reload the current app
       drby switch INSTANCE_NAME [options]               # Switch to the specified instance
       drby bundle                                       # unzips all gems in vendor/cache for deployment to droiuby\n"

  o.separator ""
  o.separator "options:"
  o.on('-h','--host HOST_IP','The IP Address of the host computer (for droiuby live mode)') { |b| $droiuby_host = b }
  o.on('-d','--device DEVICE_IP','The IP Address of the Android Device') { |b| $device_ip = b }
  o.parse!
end

command = ARGV[0]

def valid_statement?(stmt)
  begin
    catch(:x) { eval("throw :x; #{stmt}") }
  rescue SyntaxError=>e
    return false
  end
  return true
end

project = Project.new

case command
  when 'new'
    project_name = ARGV[1]

    if project_name.blank?
        puts "PROJECT_NAME is required"
        puts "Usage: drby new PROJECT_NAME [options]"
        exit(1)
    end
    project.create(project_name,'')
  when 'reload'
    project_name = ARGV[1]
    project.package(project_name, nil, 'true')
    project.upload(project_name, $device_ip, nil, false, false)
    project.reload($device_ip)
  when 'console'
    puts "droiuby console"
    while buf = Readline.readline("droiuby >  ", true)

      Readline::HISTORY.pop if /^\s*$/ =~ buf

      if ( buf=='refresh!' || buf=='reload!')
        project.reload($device_ip)
        next
      end

      if (buf == 'clear')
        system "clear" unless system "cls"
        next
      end

      exit(1) if buf=='exit' || buf=='quit'

      begin
          while !Ripper.sexp(buf) || !valid_statement?(buf)
              buf = buf + "\n" + Readline.readline("droiuby ?> ", true) + "\n"
          end
      rescue Interrupt
        puts "\n"
        next
      end
      next if buf.blank?

      begin
        res = JSON.parse(project.command(buf, $device_ip))
        puts res['result']
      rescue EOFError=>e
        puts 'cannot communicate with the device. make sure it is connected and the WebConsole is started'
      end
      
    end
  when 'list'
    project.list($device_ip)
  when 'switch'
    instance_name = nil
    unless ARGV[1].blank?
      instance_name  = ARGV[1]
    else
      puts "instance name required."
      puts 'To get a list of instances you may:'
      puts "drby list"
      puts "     "
      puts "Usage: drby switch INSTANCE_NAME"
      exit(1)
    end
    project.switch(instance_name, $device_ip)
  when 'autostart' 
    switch = ARGV[1]
    if switch.blank?
      puts "Usage: drby autostart on|off [NAMESPACE] [options]"
      exit(1)
    end
    project.autostart(switch, ARGV[2], $device_ip) 
  when 'pack'
    project_name = nil
    unless ARGV[1].blank?
      project_name = ARGV[1]
    else
      if !File.exists?('config.droiuby')
         puts 'current directory is not a valid droiuby project'
         exit(1)
      end
    end
    project.package(project_name) 
  when 'framework'
    if ARGV[1] == 'update'
        project = Project.new
        project.framework(nil, ARGV[2])
        exit(1)
    end
  when 'go'
    project_name = nil

    unless ARGV[1].blank?
      project_name = ARGV[1]
    end
    
    project.execute(project_name, $device_ip, $droiuby_host) 
  when 'bundle'
    project.bundle
  when 'live'
    project_name = nil

    if ARGV[1]
      project_name = ARGV[1]
    end

    project.live(project_name, $device_ip, $droiuby_host, '')
  else
    puts options
end