require 'listen/options'
require 'listen/record'
require 'listen/change'

module Listen
  module Adapter
    class Base
      attr_reader :options

      # TODO: only used by tests
      DEFAULTS = {}

      attr_reader :config

      def initialize(config)
        @started = false
        @config = config

        @configured = nil

        fail 'No directories to watch!' if config.directories.empty?

        defaults = self.class.const_get('DEFAULTS')
        @options = Listen::Options.new(config.adapter_options, defaults)
      rescue
        _log_exception 'adapter config failed: %s:%s called from: %s', caller
        raise
      end

      # TODO: it's a separate method as a temporary workaround for tests
      def configure
        if @configured
          _log(:warn, 'Adapter already configured!')
          return
        end

        @configured = true

        @callbacks ||= {}
        config.directories.each do |dir|
          callback = @callbacks[dir] || lambda do |event|
            _process_event(dir, event)
          end
          @callbacks[dir] = callback
          _configure(dir, &callback)
        end

        @snapshots ||= {}
        # TODO: separate config per directory (some day maybe)
        change_config = Change::Config.new(config.queue, config.silencer)
        config.directories.each do |dir|
          record = Record.new(dir)
          snapshot = Change.new(change_config, record)
          @snapshots[dir] = snapshot
        end
      end

      def started?
        @started
      end

      def start
        configure

        if started?
          _log(:warn, 'Adapter already started!')
          return
        end

        @started = true

        calling_stack = caller.dup
        Listen::Internals::ThreadPool.add do
          begin
            @snapshots.values.each do |snapshot|
              _timed('Record.build()') { snapshot.record.build }
            end
            _run
          rescue
            msg = 'run() in thread failed: %s:\n'\
              ' %s\n\ncalled from:\n %s'
            _log_exception(msg, calling_stack)
            raise # for unit tests mostly
          end
        end
      end

      def stop
        _stop
      end

      def self.usable?
        const_get('OS_REGEXP') =~ RbConfig::CONFIG['target_os']
      end

      private

      def _stop
      end

      def _timed(title)
        start = Time.now.to_f
        yield
        diff = Time.now.to_f - start
        Listen::Logger.info format('%s: %.05f seconds', title, diff)
      rescue
        Listen::Logger.warn "#{title} crashed: #{$ERROR_INFO.inspect}"
        raise
      end

      # TODO: allow backend adapters to pass specific invalidation objects
      # e.g. Darwin -> DirRescan, INotify -> MoveScan, etc.
      def _queue_change(type, dir, rel_path, options)
        @snapshots[dir].invalidate(type, rel_path, options)
      end

      def _log(*args, &block)
        self.class.send(:_log, *args, &block)
      end

      def _log_exception(msg, caller_stack)
        formatted = format(
          msg,
          $ERROR_INFO,
          $ERROR_POSITION * "\n",
          caller_stack * "\n"
        )

        _log(:error, formatted)
      end

      def self._log(*args, &block)
        Listen::Logger.send(*args, &block)
      end
    end
  end
end
