module Docs
  extend self

  def call(env)
    request = ActionDispatch::Request.new env
    version = Api.const_get request.params[:version].upcase

    Rack::Response.new.tap do |response|
      if request.path.ends_with?('json')
        response.body = [ swagger_json(version) ]
      else
        json_path = request.path + '.json'
        response.body = [ swagger_page(json_path) ]
      end
    end
  end

  private

  def swagger_json(version)
    Swagger::Blocks.build_root_json([ version::Docs ]).to_json
  end

  def swagger_page(json)
    renderer.render inline: <<-ERB, locals: { json: json }
      <html>
      <head>
        <%= stylesheet_link_tag 'swagger-ui' %>
        <%= javascript_include_tag 'swagger-ui' %>
      </head>
      <body class='swagger-section'>
        <%= render 'swagger_ui/swagger_ui', discovery_url: json %>
      </body>
      </html>
    ERB
  end

  def renderer
    ActionView::Base.new ActionController::Base.view_paths
  end

  class Railtie < Rails::Railtie
    initializer 'docs.append_route' do |app|
      app.routes.append do
        get 'api/:version/docs' => Docs
      end
    end
  end
end