# frozen_string_literal: true

#  Copyright 2020-Present Couchbase, Inc.
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.

require "logger"

module Couchbase
  # Set log level
  #
  # @note The level might be also be set with environment variable +COUCHBASE_BACKEND_LOG_LEVEL+
  #
  # @param [Symbol] level new log level.
  #
  #   Allowed levels (in order of decreasing verbosity):
  #   * +:trace+
  #   * +:debug+
  #   * +:info+ (default)
  #   * +:warn+
  #   * +:error+
  #   * +:critical+
  #   * +:off+
  #
  # @return [void]
  def self.log_level=(level)
    Backend.set_log_level(level)
  end

  # Get current log level
  #
  # @return [Symbol] current log level
  def self.log_level
    Backend.get_log_level
  end

  # Return logger associated with the library
  def self.logger
    @logger # rubocop:disable ThreadSafety/ClassInstanceVariable
  end

  # Associate logger with the library
  #
  # The log messages, that are generated by extension might come with out of order timestamps, in order to reduce number
  # of switches between Ruby and Native code.
  #
  # @param [Logger] logger an object implementing logging interface, e.g. stdlib Logger, or something that responds to
  #   "level"-methods like +#debug+, +#error+, etc.
  # @param [Class] adapter_class custom implementation of the logger adapter interface between extension and ruby code.
  #   See {Utils::StdlibLoggerAdapter} and {Utils::GenericLoggerAdapter}
  # @param [Boolean] verbose if true, the message will also include source code location, where the message was
  #   generated (if available)
  # @param [Symbol] level log level, see {::log_level=} for allowed values
  #
  # @example Specify custom logger and limit core messages to debug level
  #   Couchbase.set_logger(Logger.new(STDERR), level: :debug)
  #
  # @since 3.4.0
  def self.set_logger(logger, adapter_class: nil, verbose: false, level: :info)
    @logger = logger # rubocop:disable ThreadSafety/ClassInstanceVariable
    if @logger.nil? # rubocop:disable ThreadSafety/ClassInstanceVariable
      Backend.install_logger_shim(nil)
      return
    end
    shim =
      if adapter_class
        adapter_class
      elsif logger.is_a?(::Logger)
        require "couchbase/utils/stdlib_logger_adapter"
        Utils::StdlibLoggerAdapter
      else
        require "couchbase/utils/generic_logger_adapter"
        Utils::GenericLoggerAdapter
      end
    Backend.install_logger_shim(shim.new(logger, verbose: verbose), level)
  end
end
