module Devops
  module API3
    module Routes
      module ServerRoutes

        def self.registered(app)

          app.define_policy :read_servers, "Get servers"
          app.define_policy :create_servers, "Create servers"
          app.define_policy :delete_servers, "Delete servers"
          app.define_policy :deploy_servers, "Run deploy command on reserved server"
          app.define_policy :pause_servers, "Pause and unpouse servers"
          app.define_policy :reserve_servers, "Reserve and unreserve servers"

          app.get_with_headers "/servers" do
            check_policy(:read_servers)
            json Devops::API3::Handler::Server.new(request).servers.map(&:to_hash)
          end

=begin
          app.get_with_headers "/servers/:provider" do |provider|
            check_policy(:read_servers)
            check_provider(provider)
            json Devops::API3::Handler::Server.new(request).provider_servers(provider)
          end
=end

          app.get_with_headers "/servers/provider/:provider/:account" do |provider, account|
            check_policy(:read_servers)
            check_provider(provider)
            check_provider_account(provider, account)
            json Devops::API3::Handler::Server.new(request).provider_servers_with_account(provider, account)
          end

          app.get_with_headers "/server/id/:name" do |name|
            check_policy(:read_servers)
            json({id: Devops::API3::Handler::Server.new(request).server_id_by_name(name)})
          end

          hash = {}
          hash["GET"] = lambda {|id|
            check_policy(:read_servers)
            json Devops::API3::Handler::Server.new(request).server(id).to_hash
          }

          hash["DELETE"] = lambda {|id|
            check_policy(:delete_servers)
            if request["HTTP_X_STREAM"]
              stream() do |out|
                begin
                  status = Devops::API3::Handler::Server.new(request).delete_stream([id], out)
                  out << create_status(status)
                rescue IOError => e
                  logger.error e.message
                  break
                end
              end # stream
            else
              files = Devops::API3::Handler::Server.new(request).delete([id])
              json files
            end
          }
          app.multi_routes "/server/:id", hash

          app.post_with_headers "/servers/delete" do
            check_policy(:delete_servers)
            if request["HTTP_X_STREAM"]
              stream() do |out|
                begin
                  status = Devops::API3::Handler::Server.new(request).delete_stream(parser.delete_list, out)
                  out << create_status(status)
                rescue IOError => e
                  logger.error e.message
                  break
                end
              end # stream
            else
              files = Devops::API3::Handler::Server.new(request).delete(parser.delete_list)
              json files
            end
          end

          app.post_with_headers "/server/:id/deploy" do |id|
            check_policy(:deploy_servers)

            if request["HTTP_X_STREAM"]
              stream() do |out|
                status = []
                begin
                  status = Devops::API3::Handler::Server.new(request).deploy_stream(id, out)
                  out << create_status(status)
                rescue IOError => e
                  logger.error e.message
                  break
                end
              end # stream
            else
              json [ Devops::API3::Handler::Server.new(request).deploy(id) ]
            end
          end

          app.post_with_headers "/server" do
            check_policy(:create_servers)
            handler = Devops::API3::Handler::Server.new(request)
            if request["X-Stream"] or request["HTTP_X_STREAM"]
              stream() do |out|
                begin
                  status = handler.create_server_stream out
                  out << create_status(status)
                rescue IOError => e
                  logger.error e.message
                end
              end
            else
              json handler.create_server
            end
          end

          app.post_with_headers "/server/:id/pause" do |id|
            check_policy(:pause_servers)
            info = Devops::API3::Handler::Server.new(request).pause_server(id)
            create_response(info, {id: id})
          end

          app.post_with_headers "/server/:id/unpause" do |id|
            check_policy(:pause_servers)
            info = Devops::API3::Handler::Server.new(request).unpause_server(id)
            create_response(info, {id: id})
          end

          app.post_with_headers "/server/:id/reserve" do |id|
            check_policy(:reserve_servers)
            Devops::API3::Handler::Server.new(request).reserve_server(id)
            create_response("Server '#{id}' has been reserved", {id: id})
          end

          app.post_with_headers "/server/:id/unreserve" do |id|
            check_policy(:reserve_servers)
            Devops::API3::Handler::Server.new(request).unreserve_server(id)
            create_response("Server '#{id}' has been unreserved", {id: id})
          end

          app.post_with_headers "/server/:id/bootstrap" do |id|
            check_policy(:deploy_servers)

            handler = Devops::API3::Handler::Server.new(request)
            if request["X-Stream"]
              stream() do |out|
                begin
                  status = handler.bootstrap_server_stream id, out
                  out << create_status(status)
                rescue IOError => e
                  logger.error e.message
                end
              end
            else
              jid = handler.bootstrap_server(id)
              json [jid]
            end
          end

          app.post_with_headers "/server/:id/unbootstrap" do |id|
            check_policy(:deploy_servers)
            handler = Devops::API3::Handler::Server.new(request)
            if request["X-Stream"]
              stream() do |out|
                begin
                  status = handler.unbootstrap_server_stream id, out
                  out << create_status(status)
                rescue IOError => e
                  logger.error e.message
                end
              end
            else
              jid = handler.unbootstrap_server(id)
              json [jid]
            end
          end

          app.post_with_headers "/server/add" do
            check_policy(:create_servers)
            server = Devops::API3::Handler::Server.new(request).add_server()
            create_response("Server '#{server.id}' has been added", {id: server.id})
          end

          app.post_with_headers "/server/:id/tags/add" do |id|
            check_policy(:create_servers)
            Devops::API3::Handler::Server.new(request).set_tags(id)
            create_response("Added", {id: id})
          end

          app.post_with_headers "/server/:id/tags/delete" do |id|
            check_policy(:create_servers)
            Devops::API3::Handler::Server.new(request).unset_tags(id)
            create_response("Deleted", {id: id})
          end

          app.post_with_headers "/server/:id/run_list" do |id|
            check_policy(:create_servers)
            Devops::API3::Handler::Server.new(request).set_run_list(id)
            create_response("Run list has been changed", {id: id})
          end

          puts "Server routes initialized"
        end

      end
    end
  end
end
