class SassC::Engine

def dependencies

def dependencies
  raise NotRenderedError unless @loaded_urls
  Dependency.from_filenames(@loaded_urls
    .filter { |url| url.start_with?(Protocol::FILE) && url != file_url }
    .map { |url| URL.file_url_to_path(url) })
end

def file_url

def file_url
  @file_url ||= URL.path_to_file_url(File.absolute_path(filename || 'stdin'))
end

def load_paths

def load_paths
  @load_paths ||= if @options[:importer].nil?
                    (@options[:load_paths] || []) + SassC.load_paths
                  else
                    []
                  end
end

def output_path

def output_path
  @output_path ||= @options.fetch(:output_path) do
    "#{filename.delete_suffix(File.extname(filename))}.css" if filename
  end
end

def output_style

def output_style
  @output_style ||= begin
    style = @options.fetch(:style, :sass_style_nested).to_s
    style = "sass_style_#{style}" unless style.start_with?('sass_style_')
    raise InvalidStyleError unless OUTPUT_STYLES.include?(style.to_sym)
    style = style.delete_prefix('sass_style_').to_sym
    case style
    when :nested, :compact
      :expanded
    else
      style
    end
  end
end

def output_url

def output_url
  @output_url ||= (URL.path_to_file_url(File.absolute_path(output_path)) if output_path)
end

def render

def render
  return @template.dup if @template.empty?
  result = ::Sass.compile_string(
    @template,
    importer: import_handler.setup(nil),
    load_paths: load_paths,
    syntax: syntax,
    url: file_url,
    charset: @options.fetch(:charset, true),
    source_map: source_map_embed? || !source_map_file.nil?,
    source_map_include_sources: source_map_contents?,
    style: output_style,
    functions: functions_handler.setup(nil, functions: @functions),
    importers: @options.fetch(:importers, []),
    alert_ascii: @options.fetch(:alert_ascii, false),
    alert_color: @options.fetch(:alert_color, nil),
    logger: @options.fetch(:logger, nil),
    quiet_deps: @options.fetch(:quiet_deps, false),
    verbose: @options.fetch(:verbose, false)
  )
  @loaded_urls = result.loaded_urls
  @source_map = result.source_map
  return if quiet?
  css = result.css
  css += "\n" unless css.empty?
  unless @source_map.nil? || omit_source_map_url?
    url = URL.parse(output_url || file_url)
    source_mapping_url = if source_map_embed?
                           "data:application/json;base64,#{Base64.strict_encode64(@source_map)}"
                         else
                           URL.parse(source_map_file_url).route_from(url).to_s
                         end
    css += "\n/*# sourceMappingURL=#{source_mapping_url} */"
  end
  css
rescue ::Sass::CompileError => e
  @loaded_urls = e.loaded_urls
  line = e.span&.start&.line
  line += 1 unless line.nil?
  url = e.span&.url
  path = (URL.parse(url).route_from(URL.path_to_file_url("#{Dir.pwd}/")) if url&.start_with?(Protocol::FILE))
  raise SyntaxError.new(e.full_message, filename: path, line: line)
end

def source_map

def source_map
  raise NotRenderedError unless @source_map
  url = URL.parse(source_map_file_url || file_url)
  data = JSON.parse(@source_map)
  data['file'] = URL.parse(output_url).route_from(url).to_s if output_url
  data['sources'].map! do |source|
    if source.start_with?(Protocol::FILE)
      URL.parse(source).route_from(url).to_s
    else
      source
    end
  end
  JSON.generate(data)
end

def source_map_file_url

def source_map_file_url
  @source_map_file_url ||= (URL.path_to_file_url(File.absolute_path(source_map_file)) if source_map_file)
end

def syntax

def syntax
  syntax = @options.fetch(:syntax, :scss)
  syntax = :indented if syntax.to_sym == :sass
  syntax
end