module Jekyll::Algolia::Configurator

def self.algolia(key)

Returns the value of this option, or the default value

key - Algolia key to read

revert to the default value otherwise
Public: Get the value of a specific Algolia configuration option, or
def self.algolia(key)
  config = get('algolia') || {}
  value = config[key].nil? ? ALGOLIA_DEFAULTS[key] : config[key]
  # No value found but we have a method to define the default value
  if value.nil? && respond_to?("default_#{key}")
    value = send("default_#{key}")
  end
  value
end

def self.api_key

_algolia_api_key file in the Jekyll folder
Will first try to read the ENV variable. Will otherwise try to read the

Public: Return the api key
def self.api_key
  # Alway taking the ENV variable first
  return ENV['ALGOLIA_API_KEY'] if ENV['ALGOLIA_API_KEY']
  # Reading from file on disk otherwise
  source_dir = get('source')
  if source_dir
    api_key_file = File.join(source_dir, '_algolia_api_key')
    if File.exist?(api_key_file) && File.size(api_key_file).positive?
      return File.open(api_key_file).read.strip
    end
  end
  nil
end

def self.application_id

configured in Jekyll config
Will first try to read the ENV variable, and fallback to the one

Public: Return the application id
def self.application_id
  ENV['ALGOLIA_APPLICATION_ID'] || algolia('application_id')
end

def self.assert_valid_credentials

error messages for each missing credential
Returns true if everything is ok, false otherwise. Will display helpful

Public: Check that all credentials are set
def self.assert_valid_credentials
  checks = %w[application_id index_name api_key]
  checks.each do |check|
    if send(check.to_sym).nil?
      Logger.known_message("missing_#{check}")
      return false
    end
  end
  true
end

def self.config

This is a method around @config so we can mock it in the tests

Public: Access to the global configuration object
def self.config
  @config
end

def self.default_extensions_to_index

defined in the Jekyll config
Markdown files can have many different extensions. We keep the one

Public: Setting a default values to index only html and markdown files
def self.default_extensions_to_index
  markdown_ext = get('markdown_ext') || ''
  ['html'] + markdown_ext.split(',')
end

def self.default_files_to_exclude

empty array
User can still add it by manually specifying a `files_to_exclude` to an

content). We ignore it by default.
the list of the most recent posts or some landing page without much
Chances are high that the main page is not worthy of indexing (it can be

the root
Public: Setting a default value to ignore index.html/index.md files in
def self.default_files_to_exclude
  extensions_to_index.map do |extension|
    "index.#{extension}"
  end
end

def self.disable_other_plugins(config)

their values to nil values from here
If they are simply required in Gemfile, then we might need to revert
using .load_overwrites in jekyll-algolia.rb.
:jekyll_plugins group in the Gemfile, we might be able to override them
Note that if other jekyll plugins are defined as part of the
with the indexing
Public: Disable features from other Jekyll plugins that might interfere
def self.disable_other_plugins(config)
  # Disable archive pages from jekyll-archives
  config.delete('jekyll-archives')
  # Disable pagination from jekyll-paginate
  config.delete('paginate')
  # Disable pagination for jekyll-paginate-v2
  config['pagination'] = {} unless config['pagination'].is_a?(Hash)
  config['pagination']['enabled'] = false
  # Disable autopages for jekyll-paginate-v2
  config['autopages'] = {} unless config['autopages'].is_a?(Hash)
  config['autopages']['enabled'] = false
  # Disable tags from jekyll-tagging
  config.delete('tag_page_dir')
  config.delete('tag_page_layout')
  config
end

def self.dry_run?

When set to true, no indexing operations will be sent to the API

Public: Returns true if the command is run in verbose mode
def self.dry_run?
  value = get('dry_run')
  return true if value == true
  false
end

def self.extensions_to_index

Accepts both an array or a comma-separated list
Will use default values or read the algolia.extensions_to_index key.

Public: Returns a list of extensions to index
def self.extensions_to_index
  extensions = algolia('extensions_to_index')
  return [] if extensions.nil?
  extensions = extensions.split(',') if extensions.is_a? String
  extensions
end

def self.force_settings?

if they've been modified or not
When set to true, the index settings will always be updated, no matter

Public: Returns true if the command should always update the settings
def self.force_settings?
  value = get('force_settings')
  return true if value == true
  false
end

def self.get(key)

Returns the value of this configuration option, nil otherwise

key - Key to read

Public: Get the value of a specific Jekyll configuration option
def self.get(key)
  config[key]
end

def self.index_name

configured in Jekyll config
Will first try to read the ENV variable, and fallback to the one

Public: Return the index name
def self.index_name
  ENV['ALGOLIA_INDEX_NAME'] || algolia('index_name')
end

def self.index_object_ids_name

Public: Return the name of the index used to store the object ids
def self.index_object_ids_name
  "#{index_name}_object_ids"
end

def self.init(config = nil)

the default Jekyll config
config - The config passed by the `jekyll algolia` command. Default to

Public: Init the configurator with the Jekyll config
def self.init(config = nil)
  # Use the default Jekyll configuration if none specified. Silence the
  # warning about no config set
  Logger.silent { config = Jekyll.configuration } if config.nil?
  @config = config
  @config = disable_other_plugins(@config)
  self
end

def self.settings

_config.yml file
This will be a merge of default settings and the one defined in the

Public: Get the index settings
def self.settings
  return {} if algolia('settings') == false
  user_settings = algolia('settings') || {}
  ALGOLIA_DEFAULTS['settings'].merge(user_settings)
end

def self.verbose?

When set to true, more logs will be displayed

Public: Returns true if the command is run in verbose mode
def self.verbose?
  value = get('verbose')
  return true if value == true
  false
end

def self.warn_of_deprecated_options

Public: Check for any deprecated config option and warn the user
def self.warn_of_deprecated_options
  # indexing_mode is no longer used
  return if algolia('indexing_mode').nil?
  # rubocop:disable Metrics/LineLength
  Logger.log('I:')
  Logger.log('W:[jekyll-algolia] You are using the algolia.indexing_mode option which has been deprecated in v1.1')
  Logger.log('I:    Indexing is now always using an atomic diff algorithm.')
  Logger.log('I:    This option is no longer necessary, you can remove it from your _config.yml')
  Logger.log('I:')
  # rubocop:enable Metrics/LineLength
end