require 'all_seeing_eye'
require 'sinatra/base'
require 'erb'

class AllSeeingEye
  class Server < Sinatra::Base
    dir = File.dirname(File.expand_path(__FILE__))

    set :views,  "#{dir}/server/views"
    set :public, "#{dir}/server/public"
    set :static, true

    helpers do
      include Rack::Utils
      alias_method :h, :escape_html

      def current_section
        url_path request.path_info.sub('/','').split('/')[0].downcase
      end

      def current_page
        url_path request.path_info.sub('/','')
      end

      def url_path(*path_parts)
        path = [ path_prefix, path_parts ].compact.join("/")
        ('/' + path).squeeze('/')
      end
      alias_method :u, :url_path
      
      def path_prefix
        ENV['PATH_PREFIX']
      end

      def class_if_current(path = '')
        'class="current"' if current_page.split('/').any?{|p| p == path}
      end

      def tab(name, prefix = nil)
        dname = name.to_s.downcase
        path = url_path(dname)
        "<li #{class_if_current(path)}><a href='#{prefix.nil? ? '' : "#{prefix}/"}#{path}'>#{humanize name}</a></li>"
      end

      def round(float, n = 2)
        (float * (10.0 ** n)).round * (10.0 ** (-n))
      end
      
      def humanize(string)
        string.split('_').collect(&:capitalize).join(' ')
      end

      def partial?
        @partial
      end

      def partial(template, local_vars = {})
        @partial = true
        erb(template.to_sym, {:layout => false}, local_vars)
      ensure
        @partial = false
      end

    end

    def show(page, layout = true)
      response["Cache-Control"] = "max-age=0, private, must-revalidate"
      erb page.to_sym, {:layout => layout}
    end

    get "/?" do
      redirect url_path(:total)
    end
    
    get '/total' do
      @requests = AllSeeingEye::Request.search("one month ago to now")
      @counts = AllSeeingEye::Request.conglomerate(@requests)
      show :total
    end
    
    post '/search' do
      redirect url_path("/search/#{params[:query]}")
    end
    
    get '/search/:id' do
      @field = 'total'
      @query = params[:id]
      @requests = AllSeeingEye::Request.search(@query)
      @counts = AllSeeingEye::Request.conglomerate(@requests)
      show :total
    end
    
    get "/fields" do
      redirect url_path("/fields/#{AllSeeingEye::Request.field_keys.first}")
    end

    AllSeeingEye::Request.field_keys.each do |field|
      get "/fields/#{field}" do
        @field = field
        @requests = AllSeeingEye::Request.count_by_field(@field)
        show :field
      end
      
      get "/search/:id/#{field}" do
        @field = field
        @query = params[:id]
        @requests = AllSeeingEye::Request.search(@query)
        counts = Hash.new(0)
        @requests.each {|r| next if r.send(@field.to_sym).nil?; counts[r.send(@field.to_sym)] += 1}
        @requests = counts.sort {|a, b| b.last <=> a.last}
        show :field
      end

      (AllSeeingEye::Request.field_keys - [field]).each do |f|
        get %r{/fields/#{field}/(.*?)/#{f}$} do
          @field = field
          @id = params[:captures].first
          @view = f
          @requests = AllSeeingEye::Request.find_by_field(@field, :value => @id)
          @counts = Hash.new(0)
          @requests.each {|r| next if r.send(@view.to_sym).nil?; @counts[r.send(@view.to_sym)] += 1}
          @counts = @counts.sort {|a, b| b.last <=> a.last}
          show :view
        end
      end
      
      get %r{/fields/#{field}/(.*)$} do
        @field = field
        @id = params[:captures].first
        @requests = AllSeeingEye::Request.find_by_field(@field, :value => @id)
        @counts = AllSeeingEye::Request.conglomerate(@requests)
        show :total
      end
    end

    def tabs
      @tabs ||= AllSeeingEye::Request.field_keys
    end
  end
end