# frozen_string_literal: true
require_relative '../v3/importer'
module Sprockets
  module Sass
    module V4
      # class used for importing files from SCCS and SASS files
      class Importer < Sprockets::Sass::V3::Importer
        def syntax_mime_type(path)
          "text/#{syntax(path)}"
        end

        def engine_from_glob(glob, base_path, options)
          context = options[:custom][:sprockets_context]
          engine_imports = resolve_glob(context, glob, base_path).reduce(''.dup) do |imports, path|
            context.depend_on path[:file_url]
            relative_path = path[:path].relative_path_from Pathname.new(base_path).dirname
            imports << %(@import "#{relative_path}";\n)
          end
          return nil if engine_imports.empty?
          ::Sass::Engine.new engine_imports, options.merge(
            filename: base_path.to_s,
            syntax: syntax(base_path.to_s),
            importer: self,
            custom: { sprockets_context: context }
          )
        end

        # Finds all of the assets using the given glob.
        def resolve_glob(context, glob, base_path)
          base_path      = Pathname.new(base_path)
          path_with_glob = base_path.dirname.join(glob).to_s

          glob_files = Pathname.glob(path_with_glob).sort.reduce([]) do |imports, path|
            pathname = resolve(context, path, base_path)
            asset_requirable = asset_requirable?(context, pathname)
            imports << { file_url: pathname, path: path } if path != context.filename && asset_requirable
          end
          glob_files
        end

        def possible_files(context, path, base_path)
          filename = check_path_before_process(context, base_path)
          base_path = (filename.is_a?(Pathname) ? filename : Pathname.new(filename))
          super(context, path, base_path)
        end

        def check_path_before_process(context, path, a = nil)
          if path.to_s.start_with?('file://')
            path = Pathname.new(path.to_s.gsub(/\?type\=(.*)/, "?type=text/#{syntax(path)}"))  # @TODO : investigate why sometimes file:/// URLS are ending in ?type=text instead of ?type=text/scss
            asset = context.environment.load(path) # because resolve now returns file://
            asset.filename
          else
            path
          end
        end

        def stat_of_pathname(context, pathname, _path)
          filename = check_path_before_process(context, pathname)
          context.environment.stat(filename)
        end

        # @TODO find better alternative than scanning file:// string for mime type
        def content_type_of_path(context, path)
          pathname = context.resolve(path)
          content_type = pathname.nil? ? nil : pathname.to_s.scan(/\?type\=(.*)/).flatten.first unless pathname.nil?
          attributes = {}
          [content_type, attributes]
        end

        def get_context_transformers(context, content_type, path)
          available_transformers =  context.environment.transformers[content_type]
          additional_transformers = available_transformers.key?(syntax_mime_type(path)) ? available_transformers[syntax_mime_type(path)] : []
          additional_transformers.is_a?(Array) ? additional_transformers : [additional_transformers]
          css_transformers = available_transformers.key?('text/css') ? available_transformers['text/css'] : []
          css_transformers = css_transformers.is_a?(Array) ? css_transformers : [css_transformers]
          additional_transformers = additional_transformers.concat(css_transformers)
          additional_transformers
        end

        def filter_all_processors(processors)
          processors.delete_if do |processor|
            filtered_processor_classes.include?(processor) || filtered_processor_classes.any? do |filtered_processor|
              !processor.is_a?(Proc) && ((processor.class != Class && processor.class < filtered_processor) || (processor.class == Class && processor < filtered_processor))
            end
          end
        end

        def get_engines_from_attributes(_context, _attributes)
          []
        end

        def call_processor_input(processor, context, input, processors)
          if processor.respond_to?(:processors)
            processor.processors = filter_all_processors(processor.processors)
          end
          super(processor, context, input, processors)
        end

        def filtered_processor_classes
          classes = super
          classes << Sprockets::SassCompressor if defined?(Sprockets::SassCompressor)
          classes << Sprockets::SasscCompressor if defined?(Sprockets::SasscCompressor)
          classes << Sprockets::YUICompressor if defined?(Sprockets::YUICompressor)
          classes
        end
      end
    end
  end
end
