class ActionDispatch::Routing::Mapper::Mapping

:nodoc:

def app

def app
  Constraints.new(endpoint, blocks, @set.request_class)
end

def blocks

def blocks
  if options[:constraints].present? && !options[:constraints].is_a?(Hash)
    [options[:constraints]]
  else
    scope[:blocks] || []
  end
end

def constraints

def constraints
  @constraints ||= {}.tap do |constraints|
    constraints.merge!(scope[:constraints]) if scope[:constraints]
    options.except(*IGNORE_OPTIONS).each do |key, option|
      constraints[key] = option if Regexp === option
    end
    constraints.merge!(options[:constraints]) if options[:constraints].is_a?(Hash)
  end
end

def default_action

def default_action
  options[:action] || scope[:action]
end

def default_controller

def default_controller
  options[:controller] || scope[:controller]
end

def default_controller_and_action

def default_controller_and_action
  if to.respond_to?(:call)
    { }
  else
    if to.is_a?(String)
      controller, action = to.split('#')
    elsif to.is_a?(Symbol)
      action = to.to_s
    end
    controller ||= default_controller
    action     ||= default_action
    if @scope[:module] && !controller.is_a?(Regexp)
      if controller =~ %r{\A/}
        controller = controller[1..-1]
      else
        controller = [@scope[:module], controller].compact.join("/").presence
      end
    end
    if controller.is_a?(String) && controller =~ %r{\A/}
      raise ArgumentError, "controller name should not start with a slash"
    end
    controller = controller.to_s unless controller.is_a?(Regexp)
    action     = action.to_s     unless action.is_a?(Regexp)
    if controller.blank? && segment_keys.exclude?(:controller)
      message = "Missing :controller key on routes definition, please check your routes."
      raise ArgumentError, message
    end
    if action.blank? && segment_keys.exclude?(:action)
      message = "Missing :action key on routes definition, please check your routes."
      raise ArgumentError, message
    end
    if controller.is_a?(String) && controller !~ /\A[a-z_0-9\/]*\z/
      message = "'#{controller}' is not a supported controller name. This can lead to potential routing problems."
      message << " See http://guides.rubyonrails.org/routing.html#specifying-a-controller-to-use"
      raise ArgumentError, message
    end
    hash = {}
    hash[:controller] = controller unless controller.blank?
    hash[:action]     = action unless action.blank?
    hash
  end
end

def dispatcher

def dispatcher
  Routing::RouteSet::Dispatcher.new(:defaults => defaults)
end

def endpoint

def endpoint
  to.respond_to?(:call) ? to : dispatcher
end

def initialize(set, scope, path, options)

def initialize(set, scope, path, options)
  @set, @scope, @path, @options = set, scope, path, options
  @requirements, @conditions, @defaults = {}, {}, {}
  normalize_options!
  normalize_path!
  normalize_requirements!
  normalize_conditions!
  normalize_defaults!
end

def normalize_conditions!

def normalize_conditions!
  @conditions[:path_info] = path
  constraints.each do |key, condition|
    unless segment_keys.include?(key) || key == :controller
      @conditions[key] = condition
    end
  end
  required_defaults = []
  options.each do |key, required_default|
    unless segment_keys.include?(key) || IGNORE_OPTIONS.include?(key) || Regexp === required_default
      required_defaults << key
    end
  end
  @conditions[:required_defaults] = required_defaults
  via_all = options.delete(:via) if options[:via] == :all
  if !via_all && options[:via].blank?
    msg = "You should not use the `match` method in your router without specifying an HTTP method.\n" \
          "If you want to expose your action to both GET and POST, add `via: [:get, :post]` option.\n" \
          "If you want to expose your action to GET, use `get` in the router:\n" \
          "  Instead of: match \"controller#action\"\n" \
          "  Do: get \"controller#action\""
    raise msg
  end
  if via = options[:via]
    @conditions[:request_method] = Array(via).map { |m| m.to_s.dasherize.upcase }
  end
end

def normalize_defaults!

def normalize_defaults!
  @defaults.merge!(scope[:defaults]) if scope[:defaults]
  @defaults.merge!(options[:defaults]) if options[:defaults]
  options.each do |key, default|
    unless Regexp === default || IGNORE_OPTIONS.include?(key)
      @defaults[key] = default
    end
  end
  if options[:constraints].is_a?(Hash)
    options[:constraints].each do |key, default|
      if URL_OPTIONS.include?(key) && (String === default || Fixnum === default)
        @defaults[key] ||= default
      end
    end
  end
  if Regexp === options[:format]
    @defaults[:format] = nil
  elsif String === options[:format]
    @defaults[:format] = options[:format]
  end
end

def normalize_options!

def normalize_options!
  @options.reverse_merge!(scope[:options]) if scope[:options]
  path_without_format = path.sub(/\(\.:format\)$/, '')
  # Add a constraint for wildcard route to make it non-greedy and match the
  # optional format part of the route by default
  if path_without_format.match(WILDCARD_PATH) && @options[:format] != false
    @options[$1.to_sym] ||= /.+?/
  end
  if path_without_format.match(':controller')
    raise ArgumentError, ":controller segment is not allowed within a namespace block" if scope[:module]
    # Add a default constraint for :controller path segments that matches namespaced
    # controllers with default routes like :controller/:action/:id(.:format), e.g:
    # GET /admin/products/show/1
    # => { controller: 'admin/products', action: 'show', id: '1' }
    @options[:controller] ||= /.+?/
  end
  @options.merge!(default_controller_and_action)
end

def normalize_path!

def normalize_path!
  raise ArgumentError, "path is required" if @path.blank?
  @path = Mapper.normalize_path(@path)
  if required_format?
    @path = "#{@path}.:format"
  elsif optional_format?
    @path = "#{@path}(.:format)"
  end
end

def normalize_requirements!

def normalize_requirements!
  constraints.each do |key, requirement|
    next unless segment_keys.include?(key) || key == :controller
    verify_regexp_requirement(requirement) if requirement.is_a?(Regexp)
    @requirements[key] = requirement
  end
  if options[:format] == true
    @requirements[:format] ||= /.+/
  elsif Regexp === options[:format]
    @requirements[:format] = options[:format]
  elsif String === options[:format]
    @requirements[:format] = Regexp.compile(options[:format])
  end
end

def optional_format?

def optional_format?
  options[:format] != false && !path.include?(':format') && !path.end_with?('/')
end

def path_pattern

def path_pattern
  Journey::Path::Pattern.new(strexp)
end

def required_format?

def required_format?
  options[:format] == true
end

def segment_keys

def segment_keys
  @segment_keys ||= path_pattern.names.map{ |s| s.to_sym }
end

def strexp

def strexp
  Journey::Router::Strexp.compile(path, requirements, SEPARATORS)
end

def to

def to
  options[:to]
end

def to_route

def to_route
  [ app, conditions, requirements, defaults, options[:as], options[:anchor] ]
end

def verify_regexp_requirement(requirement)

def verify_regexp_requirement(requirement)
  if requirement.source =~ ANCHOR_CHARACTERS_REGEX
    raise ArgumentError, "Regexp anchor characters are not allowed in routing requirements: #{requirement.inspect}"
  end
  if requirement.multiline?
    raise ArgumentError, "Regexp multiline option is not allowed in routing requirements: #{requirement.inspect}"
  end
end