# encoding: UTF-8

module Jekyll
  class Configuration < Hash
    # Default options. Overridden by values in _config.yml.
    # Strings rather than symbols are used for compatibility with YAML.
    DEFAULTS = Configuration[{
      # Where things are
      "source"              => Dir.pwd,
      "destination"         => File.join(Dir.pwd, "_site"),
      "plugins_dir"         => "_plugins",
      "layouts_dir"         => "_layouts",
      "data_dir"            => "_data",
      "includes_dir"        => "_includes",
      "collections"         => {},

      # Handling Reading
      "safe"                => false,
      "include"             => [".htaccess"],
      "exclude"             => %w(
        Gemfile Gemfile.lock node_modules vendor/bundle/ vendor/cache/ vendor/gems/
        vendor/ruby/
      ),
      "keep_files"          => [".git", ".svn"],
      "encoding"            => "utf-8",
      "markdown_ext"        => "markdown,mkdown,mkdn,mkd,md",
      "strict_front_matter" => false,

      # Filtering Content
      "show_drafts"         => nil,
      "limit_posts"         => 0,
      "future"              => false,
      "unpublished"         => false,

      # Plugins
      "whitelist"           => [],
      "plugins"             => [],

      # Conversion
      "markdown"            => "kramdown",
      "highlighter"         => "rouge",
      "lsi"                 => false,
      "excerpt_separator"   => "\n\n",
      "incremental"         => false,

      # Serving
      "detach"              => false, # default to not detaching the server
      "port"                => "4000",
      "host"                => "127.0.0.1",
      "baseurl"             => nil, # this mounts at /, i.e. no subdirectory
      "show_dir_listing"    => false,

      # Output Configuration
      "permalink"           => "date",
      "paginate_path"       => "/page:num",
      "timezone"            => nil, # use the local timezone

      "quiet"               => false,
      "verbose"             => false,
      "defaults"            => [],

      "liquid"              => {
        "error_mode" => "warn",
      },

      "rdiscount"           => {
        "extensions" => [],
      },

      "redcarpet"           => {
        "extensions" => [],
      },

      "kramdown"            => {
        "auto_ids"      => true,
        "toc_levels"    => "1..6",
        "entity_output" => "as_char",
        "smart_quotes"  => "lsquo,rsquo,ldquo,rdquo",
        "input"         => "GFM",
        "hard_wrap"     => false,
        "footnote_nr"   => 1,
      },
    }.map { |k, v| [k, v.freeze] }].freeze

    class << self
      # Static: Produce a Configuration ready for use in a Site.
      # It takes the input, fills in the defaults where values do not
      # exist, and patches common issues including migrating options for
      # backwards compatiblity. Except where a key or value is being fixed,
      # the user configuration will override the defaults.
      #
      # user_config - a Hash or Configuration of overrides.
      #
      # Returns a Configuration filled with defaults and fixed for common
      # problems and backwards-compatibility.
      def from(user_config)
        Utils.deep_merge_hashes(DEFAULTS, Configuration[user_config].stringify_keys)
          .fix_common_issues.add_default_collections
      end
    end

    # Public: Turn all keys into string
    #
    # Return a copy of the hash where all its keys are strings
    def stringify_keys
      reduce({}) { |hsh, (k, v)| hsh.merge(k.to_s => v) }
    end

    def get_config_value_with_override(config_key, override)
      override[config_key] || self[config_key] || DEFAULTS[config_key]
    end

    # Public: Directory of the Jekyll source folder
    #
    # override - the command-line options hash
    #
    # Returns the path to the Jekyll source directory
    def source(override)
      get_config_value_with_override("source", override)
    end

    def quiet(override = {})
      get_config_value_with_override("quiet", override)
    end
    alias_method :quiet?, :quiet

    def verbose(override = {})
      get_config_value_with_override("verbose", override)
    end
    alias_method :verbose?, :verbose

    def safe_load_file(filename)
      case File.extname(filename)
      when %r!\.toml!i
        Jekyll::External.require_with_graceful_fail("toml") unless defined?(TOML)
        TOML.load_file(filename)
      when %r!\.ya?ml!i
        SafeYAML.load_file(filename) || {}
      else
        raise ArgumentError, "No parser for '#{filename}' is available.
          Use a .y(a)ml or .toml file instead."
      end
    end

    # Public: Generate list of configuration files from the override
    #
    # override - the command-line options hash
    #
    # Returns an Array of config files
    def config_files(override)
      # Adjust verbosity quickly
      Jekyll.logger.adjust_verbosity(
        :quiet   => quiet?(override),
        :verbose => verbose?(override)
      )

      # Get configuration from <source>/_config.yml or <source>/<config_file>
      config_files = override.delete("config")
      if config_files.to_s.empty?
        default = %w(yml yaml).find(-> { "yml" }) do |ext|
          File.exist?(Jekyll.sanitized_path(source(override), "_config.#{ext}"))
        end
        config_files = Jekyll.sanitized_path(source(override), "_config.#{default}")
        @default_config_file = true
      end
      config_files = [config_files] unless config_files.is_a? Array
      config_files
    end

    # Public: Read configuration and return merged Hash
    #
    # file - the path to the YAML file to be read in
    #
    # Returns this configuration, overridden by the values in the file
    def read_config_file(file)
      next_config = safe_load_file(file)
      check_config_is_hash!(next_config, file)
      Jekyll.logger.info "Configuration file:", file
      next_config
    rescue SystemCallError
      if @default_config_file ||= nil
        Jekyll.logger.warn "Configuration file:", "none"
        {}
      else
        Jekyll.logger.error "Fatal:", "The configuration file '#{file}'
          could not be found."
        raise LoadError, "The Configuration file '#{file}' could not be found."
      end
    end

    # Public: Read in a list of configuration files and merge with this hash
    #
    # files - the list of configuration file paths
    #
    # Returns the full configuration, with the defaults overridden by the values in the
    # configuration files
    def read_config_files(files)
      configuration = clone

      begin
        files.each do |config_file|
          next if config_file.nil? || config_file.empty?
          new_config = read_config_file(config_file)
          configuration = Utils.deep_merge_hashes(configuration, new_config)
        end
      rescue ArgumentError => err
        Jekyll.logger.warn "WARNING:", "Error reading configuration. " \
                     "Using defaults (and options)."
        $stderr.puts err
      end

      configuration.fix_common_issues.backwards_compatibilize.add_default_collections
    end

    # Public: Split a CSV string into an array containing its values
    #
    # csv - the string of comma-separated values
    #
    # Returns an array of the values contained in the CSV
    def csv_to_array(csv)
      csv.split(",").map(&:strip)
    end

    # Public: Ensure the proper options are set in the configuration to allow for
    # backwards-compatibility with Jekyll pre-1.0
    #
    # Returns the backwards-compatible configuration
    def backwards_compatibilize
      config = clone
      # Provide backwards-compatibility
      check_auto(config)
      check_server(config)
      check_plugins(config)

      renamed_key "server_port", "port", config
      renamed_key "gems", "plugins", config
      renamed_key "layouts", "layouts_dir", config
      renamed_key "data_source", "data_dir", config

      check_pygments(config)
      check_include_exclude(config)
      check_coderay(config)
      check_maruku(config)

      config
    end

    def fix_common_issues
      config = clone

      if config.key?("paginate") && (!config["paginate"].is_a?(Integer) ||
             config["paginate"] < 1)

        Jekyll.logger.warn "Config Warning:", "The `paginate` key must be a positive" \
          " integer or nil. It's currently set to '#{config["paginate"].inspect}'."
        config["paginate"] = nil
      end

      config
    end

    def add_default_collections
      config = clone

      # It defaults to `{}`, so this is only if someone sets it to null manually.
      return config if config["collections"].nil?

      # Ensure we have a hash.
      if config["collections"].is_a?(Array)
        config["collections"] = Hash[config["collections"].map { |c| [c, {}] }]
      end

      config["collections"] = Utils.deep_merge_hashes(
        { "posts" => {} }, config["collections"]
      ).tap do |collections|
        collections["posts"]["output"] = true
        if config["permalink"]
          collections["posts"]["permalink"] ||= style_to_permalink(config["permalink"])
        end
      end

      config
    end

    def renamed_key(old, new, config, _ = nil)
      if config.key?(old)
        Jekyll::Deprecator.deprecation_message "The '#{old}' configuration" \
          " option has been renamed to '#{new}'. Please update your config" \
          " file accordingly."
        config[new] = config.delete(old)
      end
    end

    private
    def style_to_permalink(permalink_style)
      case permalink_style.to_sym
      when :pretty
        "/:categories/:year/:month/:day/:title/"
      when :none
        "/:categories/:title:output_ext"
      when :date
        "/:categories/:year/:month/:day/:title:output_ext"
      when :ordinal
        "/:categories/:year/:y_day/:title:output_ext"
      else
        permalink_style.to_s
      end
    end

    # Private: Checks if a given config is a hash
    #
    # extracted_config - the value to check
    # file - the file from which the config was extracted
    #
    # Raises an ArgumentError if given config is not a hash
    private
    def check_config_is_hash!(extracted_config, file)
      unless extracted_config.is_a?(Hash)
        raise ArgumentError, "Configuration file: (INVALID) #{file}".yellow
      end
    end

    private
    def check_auto(config)
      if config.key?("auto") || config.key?("watch")
        Jekyll::Deprecator.deprecation_message "Auto-regeneration can no longer" \
                            " be set from your configuration file(s). Use the" \
                            " --[no-]watch/-w command-line option instead."
        config.delete("auto")
        config.delete("watch")
      end
    end

    private
    def check_server(config)
      if config.key?("server")
        Jekyll::Deprecator.deprecation_message "The 'server' configuration option" \
                            " is no longer accepted. Use the 'jekyll serve'" \
                            " subcommand to serve your site with WEBrick."
        config.delete("server")
      end
    end

    private
    def check_pygments(config)
      if config.key?("pygments")
        Jekyll::Deprecator.deprecation_message "The 'pygments' configuration option" \
                            " has been renamed to 'highlighter'. Please update your" \
                            " config file accordingly. The allowed values are 'rouge', " \
                            "'pygments' or null."

        config["highlighter"] = "pygments" if config["pygments"]
        config.delete("pygments")
      end
    end

    private
    def check_include_exclude(config)
      %w(include exclude).each do |option|
        if config[option].is_a?(String)
          Jekyll::Deprecator.deprecation_message "The '#{option}' configuration option" \
            " must now be specified as an array, but you specified" \
            " a string. For now, we've treated the string you provided" \
            " as a list of comma-separated values."
          config[option] = csv_to_array(config[option])
        end
        config[option].map!(&:to_s) if config[option]
      end
    end

    private
    def check_coderay(config)
      if (config["kramdown"] || {}).key?("use_coderay")
        Jekyll::Deprecator.deprecation_message "Please change 'use_coderay'" \
          " to 'enable_coderay' in your configuration file."
        config["kramdown"]["use_coderay"] = config["kramdown"].delete("enable_coderay")
      end
    end

    private
    def check_maruku(config)
      if config.fetch("markdown", "kramdown").to_s.casecmp("maruku").zero?
        Jekyll.logger.abort_with "Error:", "You're using the 'maruku' " \
          "Markdown processor, which has been removed as of 3.0.0. " \
          "We recommend you switch to Kramdown. To do this, replace " \
          "`markdown: maruku` with `markdown: kramdown` in your " \
          "`_config.yml` file."
      end
    end

    # Private: Checks if the `plugins` config is a String
    #
    # config - the config hash
    #
    # Raises a Jekyll::Errors::InvalidConfigurationError if the config `plugins`
    # is a string
    private
    def check_plugins(config)
      if config.key?("plugins") && config["plugins"].is_a?(String)
        Jekyll.logger.error "Configuration Error:", "You specified the" \
          " `plugins` config in your configuration file as a string, please" \
          " use an array instead. If you wanted to set the directory of your" \
          " plugins, use the config key `plugins_dir` instead."
        raise Jekyll::Errors::InvalidConfigurationError,
          "'plugins' should not be a string, but was: " \
          "#{config["plugins"].inspect}. Use 'plugins_dir' instead."
      end
    end
  end
end
