class Envirobly::ContainerShell

def connect_data

def connect_data
  @connect_data ||= begin
    api = Envirobly::Api.new
    api.create_service_shell_connection(@params).object
  end
end

def env_vars

def env_vars
  credentials = connect_data.fetch("open_tunnel_credentials")
  result = sprintf(
    join(AWS_ENV),
    credentials.fetch("access_key_id"),
    credentials.fetch("secret_access_key"),
    credentials.fetch("session_token")
  )
  if options.shell.present?
    result = join "ENVIROBLY_SERVICE_INTERACTIVE_SHELL='#{options.shell}'", result
  end
  if options.user.present?
    result = join "ENVIROBLY_SERVICE_SHELL_USER='#{options.user}'", result
  end
  result
end

def exec(command = nil)

def exec(command = nil)
  with_private_key do
    system join(env_vars, ssh, user_and_host, command)
  end
end

def initialize(service_name, options)

def initialize(service_name, options)
  @service_name = service_name
  @options = options
  commit = Envirobly::Git::Commit.new "HEAD"
  @params = {
    account_id: options.account_id || Envirobly::Defaults::Account.new.id,
    project_name: options.project_name || File.basename(Dir.pwd), # TODO: Extract into Defaults::ProjectName
    project_id: options.project_id,
    environ_name: options.environ_name || commit.current_branch,
    service_name: service_name,
    instance_slot: options.instance_slot || 0
  }
  if options.project_name.blank? && options.account_id.blank? && options.project_id.blank?
    @params[:project_id] = Envirobly::Defaults::Project.new.id
  end
end

def join(*parts)

def join(*parts)
  parts.flatten.compact.join(" ")
end

def rsync(source, destination)

def rsync(source, destination)
  with_private_key do
    system join(
      env_vars,
      %(rsync #{options.args} -e "#{ssh}"),
      source.sub("#{service_name}:", "#{user_and_host}:"),
      destination.sub("#{service_name}:", "#{user_and_host}:")
    )
  end
end

def ssh

def ssh
  sprintf(
    join(SSH),
    @private_key_path,
    connect_data.fetch("instance").fetch("aws_id"),
    connect_data.fetch("region")
  )
end

def user_and_host

def user_and_host
  sprintf USER_AND_HOST, connect_data.fetch("instance").fetch("private_ipv4")
end

def with_private_key

def with_private_key
  Tempfile.create do |file|
    file.write connect_data.fetch("instance").fetch("private_key")
    file.flush
    @private_key_path = file.path
    yield
  end
end