class Rails::Command::ServerCommand

:nodoc:

def self.banner(*)

def self.banner(*)
  "rails server -u [thin/puma/webrick] [options]"
end

def early_hints

def early_hints
  options[:early_hints]
end

def environment

def environment
  options[:environment] || Rails::Command.environment
end

def host

def host
  if options[:binding]
    options[:binding]
  else
    default_host = environment == "development" ? "localhost" : "0.0.0.0"
    ENV.fetch("BINDING", default_host)
  end
end

def initialize(args, local_options, *)

def initialize(args, local_options, *)
  super
  @original_options = local_options - %w( --restart )
end

def log_to_stdout?

def log_to_stdout?
  options.fetch(:log_to_stdout) do
    options[:daemon].blank? && environment == "development"
  end
end

def perform

def perform
  extract_environment_option_from_argument
  set_application_directory!
  prepare_restart
  Rails::Server.new(server_options).tap do |server|
    # Require application after server sets environment to propagate
    # the --environment option.
    require APP_PATH
    Dir.chdir(Rails.application.root)
    if server.serveable?
      print_boot_information(server.server, server.served_url)
      after_stop_callback = -> { say "Exiting" unless options[:daemon] }
      server.start(after_stop_callback)
    else
      say rack_server_suggestion(options[:using])
    end
  end
end

def pid

def pid
  File.expand_path(options[:pid] || ENV.fetch("PIDFILE", DEFAULT_PIDFILE))
end

def port

def port
  options[:port] || ENV.fetch("PORT", DEFAULT_PORT).to_i
end

def prepare_restart

def prepare_restart
  FileUtils.rm_f(pid) if options[:restart]
end

def print_boot_information(server, url)

def print_boot_information(server, url)
  say <<~MSG
    => Booting #{ActiveSupport::Inflector.demodulize(server)}
    => Rails #{Rails.version} application starting in #{Rails.env} #{url}
    => Run `bin/rails server --help` for more startup options
  MSG
end

def rack_server_suggestion(server)

def rack_server_suggestion(server)
  if server.in?(RACK_SERVERS)
    <<~MSG
      Could not load server "#{server}". Maybe you need to the add it to the Gemfile?
        gem "#{server}"
      Run `bin/rails server --help` for more options.
    MSG
  else
    error = CorrectableError.new("Could not find server '#{server}'.", server, RACK_SERVERS)
    if error.respond_to?(:detailed_message)
      formatted_message = error.detailed_message
    else
      formatted_message = error.message
    end
    <<~MSG
      #{formatted_message}
      Run `bin/rails server --help` for more options.
    MSG
  end
end

def restart_command

def restart_command
  "bin/rails server #{@original_options.join(" ")} --restart"
end

def server_options

def server_options
  {
    user_supplied_options: user_supplied_options,
    server:                options[:using],
    log_stdout:            log_to_stdout?,
    Port:                  port,
    Host:                  host,
    DoNotReverseLookup:    true,
    config:                options[:config],
    environment:           environment,
    daemonize:             options[:daemon],
    pid:                   pid,
    caching:               options[:dev_caching],
    restart_cmd:           restart_command,
    early_hints:           early_hints
  }
end

def user_supplied_options

def user_supplied_options
  @user_supplied_options ||= begin
    # Convert incoming options array to a hash of flags
    #   ["-p3001", "-C", "--binding", "127.0.0.1"] # => {"-p"=>true, "-C"=>true, "--binding"=>true}
    user_flag = {}
    @original_options.each do |command|
      if command.start_with?("--")
        option = command.split("=")[0]
        user_flag[option] = true
      elsif command =~ /\A(-.)/
        user_flag[Regexp.last_match[0]] = true
      end
    end
    # Collect all options that the user has explicitly defined so we can
    # differentiate them from defaults
    user_supplied_options = []
    self.class.class_options.select do |key, option|
      if option.aliases.any? { |name| user_flag[name] } || user_flag["--#{option.name}"]
        name = option.name.to_sym
        case name
        when :port
          name = :Port
        when :binding
          name = :Host
        when :dev_caching
          name = :caching
        when :daemonize
          name = :daemon
        end
        user_supplied_options << name
      end
    end
    user_supplied_options << :Host if ENV["HOST"] || ENV["BINDING"]
    user_supplied_options << :Port if ENV["PORT"]
    user_supplied_options << :pid if ENV["PIDFILE"]
    user_supplied_options.uniq
  end
end