#!/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
$app_name = 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 standalone [PROJECT_NAME] --package JAVA_PACKAGE   # creates a standalone android project for the current app
            [--name APP_NAME]
       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('-n','--name app_name','The name of the app that appears in the launcher') {|b| $app_name =b }
  o.on('-p','--package java_package','The java package name to use') {|b| $java_package = b}
  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
    
    app_name = if $app_name.nil?
              :prompt
            else
              $app_name
            end

    project.create(project_name, app_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 'standalone'
    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

    if $java_package.nil?
      puts '--package [JAVA_PACKAGE] is required.'
      exit(1)
    end
    project.standalone(project_name, $java_package, $app_name,'')
  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]
    else
      if !File.exists?('config.droiuby')
         puts 'current directory is not a valid droiuby project'
         exit(1)
      end
    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