class Fanforce::PluginFactory::CLI::Iron
  include Fanforce::PluginFactory::CLI::Utils

  require_gem 'iron_worker', 'iron_worker'

  attr_reader :plugin

  def initialize(plugin)
    @plugin = plugin
  end

  def workers_dir
    @workers_dir ||= "#{plugin.dir}/workers"
  end

  def upload(environment, worker_filename=nil)
    return log "#{'Skipped '.format(:bold)} no workers folder was found" if !File.directory?(workers_dir)

    worker_filename = worker_filename.gsub('.worker', '') if worker_filename
    env_vars = Fanforce::PluginFactory::CLI::Env.new(plugin).vars(environment) || {}
    return puts "#{'Skipped '.format(:bold)} #{environment.to_s.titleize} is missing IRON_TOKEN and/or IRON_PROJECT_ID env variables" if env_vars['IRON_TOKEN'].blank? or env_vars['IRON_PROJECT_ID'].blank?

    Dir.chdir(workers_dir) do
      workers = Dir['*.rb']
      return puts "#{'Skipped  '.format(:bold)} #{environment.to_s.titleize} has 0 workers" if workers.size == 0

      upload_processes = []
      workers.each do |filename|
        next if worker_filename and !filename.include?(worker_filename)
        zipped_filepath = compile_worker(filename, environment, env_vars)
        upload_processes << upload_worker(filename, environment, env_vars, zipped_filepath)
      end
      upload_processes.each { |pid| Process.waitpid(pid) }
    end
  end

  def compile_worker(filename, environment, env_vars)
    puts "#{'Compiling'.format(:green,:bold)} #{filename.gsub('.rb', '')} to #{environment.to_s.titleize}..."
    code_name = filename.gsub('.rb', '')

    dockerized_dir = "#{workers_dir}/dockerized/#{code_name}"
    dockerized_dir_relative = "workers/dockerized/#{code_name}"
    Dir.mkdir("#{workers_dir}/dockerized") if !File.directory?("#{workers_dir}/dockerized")

    zipped_dir = "#{workers_dir}/zipped"
    zipped_filepath = "#{zipped_dir}/#{code_name}.#{env(environment)}.zip"
    Dir.mkdir(zipped_dir) if !File.directory?(zipped_dir)

    if !File.directory?(dockerized_dir)
      puts "Creating #{dockerized_dir_relative}/"
      Dir.mkdir(dockerized_dir)
    end

    puts "Copying /workers/#{filename} to #{dockerized_dir_relative}/#{filename}"
    File.open("#{dockerized_dir}/#{filename}", 'w') do |f|
      f.write File.read("#{plugin.dir}/workers/#{filename}")
    end

    puts "Copying /Gemfile to #{dockerized_dir_relative}/Gemfile"
    File.open("#{dockerized_dir}/Gemfile", 'w') do |f|
      f.write File.read("#{plugin.dir}/Gemfile").gsub("ruby '2.1.6'", "ruby '2.1.4'")
    end

    puts "Copying /Gemfile.lock to #{dockerized_dir_relative}/Gemfile.lock"
    File.open("#{dockerized_dir}/Gemfile.lock", 'w') do |f|
      f.write File.read("#{plugin.dir}/Gemfile.lock")
    end

    if File.directory?("#{plugin.dir}/lib") and !File.directory?("#{dockerized_dir}/lib")
      puts "Copying /lib/ to #{dockerized_dir_relative}/lib/"
      FileUtils.copy_entry("#{plugin.dir}/lib", "#{dockerized_dir}/lib")
    end

    if File.directory?("#{plugin.dir}/mailers") and !File.directory?("#{dockerized_dir}/mailers")
      puts "Copying /mailers/ to #{dockerized_dir_relative}/mailers/"
      FileUtils.copy_entry("#{plugin.dir}/mailers", "#{dockerized_dir}/mailers")
    end

    puts "Setting up ENV for #{environment.to_s.titleize} (#{env_vars.size} variables)"
    File.open("#{dockerized_dir}/env.#{env(environment)}.rb", 'w') {|f| f.write Fanforce::PluginFactory::CLI::Env.convert_hash_to_ruby_env(env_vars) }

    puts "Dockerizing #{File.expand_path(dockerized_dir)}"
    console_command("docker run --rm -v \"#{File.expand_path(dockerized_dir)}\":/worker -w /worker iron/images:ruby-2.1 sh -c 'bundle install --standalone'", true)
    console_command("zip -r #{zipped_filepath} #{dockerized_dir}")

    return zipped_filepath
  end

  def upload_worker(filename, environment, env_vars, zipped_filepath)
    code_name = filename.gsub('.rb', '')
    puts "#{'Uploading'.format(:green,:bold)} #{code_name} to #{environment.to_s.titleize}..."

    fork do
      begin
        puts console_command("iron --project-id #{env_vars['IRON_PROJECT_ID']} --token #{env_vars['IRON_TOKEN']} worker upload --stack ruby-2.1 --name #{code_name} #{zipped_filepath} ruby #{filename}")
      rescue Exception => e
        puts "#{'Aborted  '.format(:red,:bold)} upload of #{filename.gsub('.worker', '')} to #{environment.to_s.titleize}..."
        puts e.message
        puts e.backtrace
        puts ''
      end
    end
  end

  def current_factory_version
    `bundle list`.lines.each do |line|
      return $1 if line =~ /fanforce-plugin-factory \(([A-Za-z0-9.-]+)\)/
    end
    error 'fanforce-plugin-factory version was not found in `bundle list`'
  end

  def upload_iron_worker(iron_worker, code, filename, environment)
  end

end