module Jekyll
  class PluginManager
    attr_reader :site

    # Create an instance of this class.
    #
    # site - the instance of Jekyll::Site we're concerned with
    #
    # Returns nothing
    def initialize(site)
      @site = site
    end

    # Require all the plugins which are allowed.
    #
    # Returns nothing
    def conscientious_require
      require_theme_deps if site.theme
      require_plugin_files
      require_gems
      deprecation_checks
    end

    # Require each of the gem plugins specified.
    #
    # Returns nothing.
    def require_gems
      Jekyll::External.require_with_graceful_fail(
        site.gems.select { |plugin| plugin_allowed?(plugin) }
      )
    end

    # Require each of the runtime_dependencies specified by the theme's gemspec.
    #
    # Returns false only if no dependencies have been specified, otherwise nothing.
    def require_theme_deps
      return false unless site.theme.runtime_dependencies
      site.theme.runtime_dependencies.each do |dep|
        next if dep.name == "jekyll"
        External.require_with_graceful_fail(dep.name) if plugin_allowed?(dep.name)
      end
    end

    def self.require_from_bundler
      if !ENV["JEKYLL_NO_BUNDLER_REQUIRE"] && File.file?("Gemfile")
        require "bundler"

        Bundler.setup
        required_gems = Bundler.require(:jekyll_plugins)
        message = "Required #{required_gems.map(&:name).join(", ")}"
        Jekyll.logger.debug("PluginManager:", message)
        ENV["JEKYLL_NO_BUNDLER_REQUIRE"] = "true"

        true
      else
        false
      end
    end

    # Check whether a gem plugin is allowed to be used during this build.
    #
    # plugin_name - the name of the plugin
    #
    # Returns true if the plugin name is in the whitelist or if the site is not
    #   in safe mode.
    def plugin_allowed?(plugin_name)
      !site.safe || whitelist.include?(plugin_name)
    end

    # Build an array of allowed plugin gem names.
    #
    # Returns an array of strings, each string being the name of a gem name
    #   that is allowed to be used.
    def whitelist
      @whitelist ||= Array[site.config["whitelist"]].flatten
    end

    # Require all .rb files if safe mode is off
    #
    # Returns nothing.
    def require_plugin_files
      unless site.safe
        plugins_path.each do |plugin_search_path|
          plugin_files = Utils.safe_glob(plugin_search_path, File.join("**", "*.rb"))
          Jekyll::External.require_with_graceful_fail(plugin_files)
        end
      end
    end

    # Public: Setup the plugin search path
    #
    # Returns an Array of plugin search paths
    def plugins_path
      if site.config["plugins_dir"].eql? Jekyll::Configuration::DEFAULTS["plugins_dir"]
        [site.in_source_dir(site.config["plugins_dir"])]
      else
        Array(site.config["plugins_dir"]).map { |d| File.expand_path(d) }
      end
    end

    def deprecation_checks
      pagination_included = (site.config["plugins"] || []).include?("jekyll-paginate") ||
        defined?(Jekyll::Paginate)
      if site.config["paginate"] && !pagination_included
        Jekyll::Deprecator.deprecation_message "You appear to have pagination " \
          "turned on, but you haven't included the `jekyll-paginate` gem. " \
          "Ensure you have `plugins: [jekyll-paginate]` in your configuration file."
      end
    end
  end
end
