require 'rbbt-util'
require 'rbbt/util/simpleopt'

$0 = "rbbt #{$previous_commands*""} #{ File.basename(__FILE__) }" if $previous_commands

options = SOPT.setup <<EOF
Start an rbbt app

$ rbbt workflow server [options] <Workflow>

-h--help Print this help
-e--environment* Execution environment: production or development
-Ho--Host* Host name
-B--Bind* Bind IP
-p--port* TCP port
-s--server* Server type:  thin, webrick, unicorn, etc
-f--finder Start server with finder functionality
-RS--Rserve_session* Rserve session to use, otherwise start new one
-wd--workdir* Change the working directory of the workflow
-W--workflows* List of additional workflows to load
-R--requires* Require a list of files
--views* Directory with view templates
--stream Activate streaming of workflow tasks
--export* Export workflow tasks (asynchronous)
--export_asynchronous* Export workflow tasks as asynchronous
--export_synchronous* Export workflow tasks as synchronous
--export_exec* Export workflow tasks as exec
--export_stream* Export workflow tasks as stream
--options* Additional options for server (e.g. option1=value1;option2=value2)
EOF

if options[:help]
  if defined? rbbt_usage
    rbbt_usage 
  else
    puts SOPT.usage
  end
  exit 0
end

if options[:workdir]
  require 'rbbt/workflow'
  Workflow.workdir = options[:workdir]
end

options[:Port] ||= options[:port]
options[:Host] ||= "0.0.0.0"
options[:Bind] ||= "0.0.0.0"

workflow = ARGV.shift
workflows = options[:workflows] || "" 
requires = options[:requires] || "" 

workflow = File.expand_path(workflow) if File.exist?(workflow)

ENV["RServe-session"] = options[:RServe_session] || workflow

server = options[:server] || 'puma'

exports = options[:export].split(/\s*,/) if options[:export]
stream_exports = options[:export_stream].split(/\s*,/) if options[:export_stream]
async_exports = options[:export_asynchronous].split(/\s*,/) if options[:export_asynchronous]
sync_exports = options[:export_synchronous].split(/\s*,/) if options[:export_synchronous]
exec_exports = options[:export_exec].split(/\s*,/) if options[:export_exec]

TmpFile.with_file do |app_dir|
  Misc.in_dir(app_dir) do
    app_dir = Path.setup(app_dir.dup)
    Open.write(app_dir.etc.target_workflow.find, workflow)

    Open.write(app_dir.etc.target_workflow_exports.find, exports * "\n") if exports
    Open.write(app_dir.etc.target_workflow_stream_exports.find, stream_exports * "\n") if stream_exports
    Open.write(app_dir.etc.target_workflow_async_exports.find, async_exports * "\n") if async_exports
    Open.write(app_dir.etc.target_workflow_sync_exports.find, sync_exports * "\n") if sync_exports
    Open.write(app_dir.etc.target_workflow_exec_exports.find, exec_exports * "\n") if exec_exports

    Open.write(app_dir.etc.workflows.find, workflows.split(/,\s*/)*"\n") if workflows and not workflows.empty?
    Open.write(app_dir.etc.requires.find, requires.split(/,\s*/)*"\n") if requires and not requires.empty? 

    require 'rack'
    ENV["RBBT_FINDER"] = "true" if options.include?(:finder)
    ENV["RACK_ENV"] = options[:environment] if options.include?(:environment)
    ENV["RBBT_VIEWS_DIR"] = options[:views] if options.include?(:views)

    if options[:stream]
      raise "No streaming available for any server other than puma" unless true or options[:server].include? 'puma'
      ENV["RBBT_WORKFLOW_TASK_STREAM"] = 'true'
    end

    config_ru_file = File.exist?('./workflow_config.ru') ? './config.ru' : Rbbt.share['workflow_config.ru'].find


    if options[:options]
      options[:options].split(";").each do |pair|
        name, _sep, value = pair.partition("=")
        name = name[1..-1].to_sym if name[0] == ':'
        options[name] = value
      end
    end

    case server
    when 'unicorn'
      `env RBBT_LOG=#{Log.severity.to_s} unicorn -c #{ Rbbt.share['unicorn.rb'].find } '#{config_ru_file}' -p #{options[:port] || "2887"}`
    when 'puma_alt'
      #`puma '#{config_ru_file}' -p #{options[:Port] || "2887"} -w 3 -t 8:32 --preload`
      `env RBBT_LOG=#{Log.severity.to_s} puma '#{config_ru_file}' -p #{options[:Port] || "2887"} -w 20 -t 10:160 --preload`
    else
      options[:config] = config_ru_file
      Rack::Server.start(options)
    end
  end
end