class SvelteOnRails::Lib::Utils

def self.asset_path(filename)

def self.asset_path(filename)
  config = SvelteOnRails::Configuration.instance
  path = (config.frontend_folder + config.components_folder).join(filename)
  manifest = config.ssr_manifest
  manifest[path.to_s.sub(/\.svelte$/, '') + '.svelte']['file']
end

def self.component_files(filename, base_path: SvelteOnRails::Configuration.instance.components_folder_full)

def self.component_files(filename, base_path: SvelteOnRails::Configuration.instance.components_folder_full)
  fn = (filename.match(/\.svelte$/) ? filename[0..-8] : filename)
  svelte_file = (base_path + fn).to_s + '.svelte'
  svelte_filename = fn + '.svelte'
  cnf = SvelteOnRails::Configuration.instance
  cf = cnf.rails_root.join('public', 'vite-ssr', asset_path(filename).sub(/.js$/, ''))
  {
    svelte_file: svelte_file,
    svelte_filename: svelte_filename,
    compiled_file: cf.to_s
  }
end

def self.file_exist_case_sensitive?(containing_dir, filename)

def self.file_exist_case_sensitive?(containing_dir, filename)
  # Combine the directory path and filename
  full_path = File.join(containing_dir, filename)
  # Check if the file exists and the path matches case-sensitively
  File.exist?(full_path) && Dir[File.join(containing_dir, "**/*")].any? do |f|
    f == full_path
  end
end

def self.gem_app_dir

def self.gem_app_dir
  File.expand_path('../../svelte_on_rails', __dir__) + '/'
end

def self.precompile(last_mtime = nil)

def self.precompile(last_mtime = nil)
  config = SvelteOnRails::Configuration.instance
  Dir.chdir(config.rails_root) do
    # run build
    cmd = "./node_modules/.bin/vite build --config vite-ssr.config.ts"
    stdout, stderr, status = Open3.capture3(cmd)
    warnings = stderr.to_s.split("\n")
    errors_matcher = Regexp.new('(Could not resolve|failed to resolve)')
    error_lines = warnings.select { |e| e.match(errors_matcher) }
    have_error = error_lines.present? || status.to_s.match(/exit 1/)
    # error handling
    if stderr.present?
      red_background = "\033[97;41m"
      light_blue_background = "\033[30;106m"
      clear_colors = "\033[0m"
      msg = "  +++  #{have_error ? 'ERROR' : 'WARNING'} compiling Svelte components#{have_error ? ' failed' : ''}#{cmd}»)  +++  "
      puts "#{have_error ? red_background : light_blue_background}#{msg}#{clear_colors}"
      warnings.each do |e|
        if e.match(errors_matcher)
          red_font = "\033[31m"
          puts "#{red_background}  #{clear_colors}#{red_font} #{e}#{clear_colors}"
        else
          puts "#{light_blue_background}  #{clear_colors}#{e}"
        end
      end
      if have_error
        puts "#{red_background}  +++  End of error message  +++  #{clear_colors}"
      else
        puts "#{light_blue_background}  +++  End of compiling warnings  +++  #{clear_colors}"
      end
      puts "#{have_error ? red_background : light_blue_background}  +++  Run «npm run build:ssr» on the console to see the original error message  +++  #{clear_colors}"
      if have_error
        cl_str = if error_lines.present?
                   "#{error_lines.join("\n")}\n\n"
                 end
        raise "Svelte components compilation failed\n\n#{cl_str}Full message:\n+++\n#{stderr}+++\n\nYou can run «npm run build:ssr» on the console to see the original error message\n"
      end
    end
    puts stdout
  end
  unless Dir.exist?(config.ssr_dist_folder)
    raise "Could not find dist folder: #{config.ssr_dist_folder}"
  end
  if last_mtime
    mtime_path = config.ssr_dist_folder.join('last_mtime')
    File.write(mtime_path, last_mtime.to_s)
  end
end

def self.puts_error(text)

def self.puts_error(text)
  red_background = "\033[97;41m"
  clear_colors = "\033[0m"
  puts "#{red_background} ERROR #{clear_colors}"
  text.split("\n").each do |line|
    puts "#{red_background}  #{clear_colors}  #{line}"
  end
end

def self.puts_warning(text)

def self.puts_warning(text)
  black_background = "\033[97;40m"
  clear_colors = "\033[0m"
  puts "#{black_background} [svelte-on-rails] WARNING #{clear_colors}"
  text.split("\n").each do |line|
    puts "#{black_background} #{clear_colors}  #{line}"
  end
end

def self.watch_changes_and_precompile

def self.watch_changes_and_precompile
  config = SvelteOnRails::Configuration.instance
  return unless config.watch_changes?
  mtime = Dir[File.join(config.components_folder_full, '**/*.svelte')].map do |file|
    File.mtime(file).to_f
  end.max || 0.0
  last = if Dir.exist?(config.ssr_dist_folder)
           mtime_path = config.ssr_dist_folder.join('last_mtime')
           (File.exist?(mtime_path) ? File.read(mtime_path).to_f : 0.0)
         end
  if !last || mtime > last
    precompile(mtime)
  end
end