require_dependency 'global_exceptions'
require_dependency 'vertice_resource'
require_dependency 'auth/default_current_user_provider'
require_dependency 'version'

module Nilavu

  # Expected less matches than what we got in a find
  class TooManyMatches < StandardError; end

  # When they try to do something they should be logged in for
  class NotLoggedIn < StandardError; end

  # When the input is somehow bad
  class InvalidParameters < StandardError; end

  # When something they want is not found
  class NotFound < StandardError; end

  # When a setting is missing
  class SiteSettingMissing < StandardError; end

  # When they don't have permission to do something
  class InvalidAccess < StandardError
    attr_reader :obj
    def initialize(msg=nil, obj=nil)
      super(msg)
      @obj = obj
    end
  end

  def self.assets_digest
    @assets_digest ||= begin
      digest = Digest::MD5.hexdigest(ActionView::Base.assets_manifest.assets.values.sort.join)

      digest
    end
  end

  def self.authenticators
    OmniauthCallbacksController::BUILTIN_AUTH + auth_providers.map(&:authenticator)
  end

  def self.auth_providers
    providers = []
    plugins.each do |p|
      next unless p.auth_providers
      p.auth_providers.each do |prov|
        providers << prov
      end
    end
    providers
  end

  def self.plugins
    @plugins ||= []
  end

  def self.display_categories
    set = Set.new

    SiteSetting.left_menu.split("|").map(&:to_s).each do |category|
      set << category
    end
    set
  end


  def self.default_categories
    set = Set.new

    SiteSetting.default_categories.split("|").map(&:to_s).each do |category|
      set << category
    end
    set
  end

  def self.default_categories_muted
    set = Set.new

    SiteSetting.default_categories_muted.split("|").map(&:to_s).each do |muted_category|
      set << muted_category
    end
    set
  end


  # Get the current base URL for the current site
  def self.current_hostname
    #if SiteSetting.force_hostname.present?
    #  SiteSetting.force_hostname
    #else
      'localhost'
    #end
  end

  def self.base_uri(default_value = "")
    if !ActionController::Base.config.relative_url_root.blank?
      ActionController::Base.config.relative_url_root
    else
      default_value
    end
  end

  def self.base_url_no_prefix
    default_port = 80
    protocol = "http"

    if SiteSetting.use_https?
      protocol = "https"
      default_port = 443
    end

    result = "#{protocol}://#{current_hostname}"

  #  port = SiteSetting.port.present? && SiteSetting.port.to_i > 0 ? SiteSetting.port.to_i : default_port
  port  = default_port
    result << ":#{SiteSetting.port}" if port != default_port
    result
  end

  def self.base_url
    base_url_no_prefix + base_uri
  end


  def self.git_version
    return $git_version if $git_version

    # load the version stamped by the "build:stamp" task
    f = Rails.root.to_s + "/config/version"
    require f if File.exists?("#{f}.rb")

    begin
      $git_version ||= `git rev-parse HEAD`.strip
    rescue
      $git_version = Nilavu::VERSION::STRING
    end
  end

  def self.current_user_provider
    @current_user_provider || Auth::DefaultCurrentUserProvider
  end

  def self.current_user_provider=(val)
    @current_user_provider = val
  end

  def self.current_cephuser_provider
    @current_cephuser_provider || Auth::DefaultCurrentCephUserProvider
  end

  def self.current_cephuser_provider=(val)
    @current_cephuser_provider = val
  end

  # all forking servers must call this
  # after fork, otherwise Nilavu will be in a bad state
  def self.after_fork
    SiteSetting.after_fork
    #Rails.cache.reconnect
    nil
  end
end
