require 'net/http' require 'net/https' require 'json' require 'optparse'

namespace :heimdall do

desc 'Register application at a Heimdall Application'
task :register do

  application_name = Rails.application.class.try(:parent_name) || Rails.application.class.try(:module_parent_name)

  options = {
    application_name: application_name,
    service_url: "https://#{application_name.underscore.dasherize}.vesputi-abc.de",
    heimdall_url: "https://heimdall.vesputi-abc.de",
  }
  option_parser = OptionParser.new
  option_parser.banner = "Usage: rake add [options]"
  option_parser.on("-h", "--heimdall ARG", String) { |heimdall_url| options[:heimdall_url] = heimdall_url }
  option_parser.on("-s", "--service ARG", String) { |service_url| options[:service_url] = service_url }
  option_parser.on("-u", "--username ARG", String) { |username| options[:username] = username }
  option_parser.on("-p", "--password ARG", String) { |password| options[:password] = password }

  args = option_parser.order!(ARGV) {}
  option_parser.parse!(args)

  #TODO: strip the trialing slash ... if there is one
  credentials = create_oauth_application_request(
    options[:heimdall_url],
    options[:service_url],
    "#{options[:application_name]} | (Registered at #{DateTime.current.to_formatted_s(:long)})",
    options[:username],
    options[:password]
  )

  if credentials
    STDERR.puts "## Sucessfully registered as '#{options[:application_name]}'"
    STDERR.puts "# Heimdall URL as '#{options[:heimdall_url]}' (change it with -h\"https://heimdall.any-whe.re/\")"
    STDERR.puts "# Service URL as '#{options[:service_url]}' (change it with -s\"https://foo.bar/\")"
    puts "HEIMDALL_SERVER_URL=#{options[:heimdall_url]}/"
    puts "HEIMDALL_APPLICATION_ID=#{credentials['uid']}"
    puts "HEIMDALL_APPLICATION_SECRET=#{credentials['secret']}"
  end
end

end

def create_oauth_application_request(heimdall_url, application_url, application_name, heimdall_username, heimdall_password)

uri = URI("#{heimdall_url}/oauth_applications_api.json")

# Create client
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
dict = {
          "oauth_application" => {
              "name" => "#{application_name}",
              "redirect_uri" =>
                "#{application_url}/auth/heimdall/callback\n" +
                "#{application_url}/auth/heimdall/callback/"
          }
      }
body = JSON.dump(dict)

# Create Request
req =  Net::HTTP::Post.new(uri)
# Add headers
req.add_field "Authorization", "Basic #{Base64.strict_encode64("#{heimdall_username}:#{heimdall_password}")}"
# Add headers
req.add_field "Content-Type", "application/json; charset=utf-8"
# Set body
req.body = body

# Fetch Request
res = http.request(req)

if res.code == "201"
  return JSON.parse(res.body)
else
  STDERR.puts "Can't Register \n\n Code #{res.code} Body: #{res.body}"
end

rescue StandardError => e

STDERR.puts "HTTP Request failed (#{e.message})"

end