# frozen_string_literal: true

module KorpCraft
  module SwapGuard
    def self.run!(root_dir:, user_data_root: nil)
      kc = File.join(root_dir, 'KorpCraft')
      staged = File.join(root_dir, '.KorpCraft.staged')
      prev = File.join(root_dir, '.KorpCraft.prev')

      # A crash between the two renames below leaves kc missing and
      # staged still present (first rename ran, second didn't) — finish it.
      if !File.directory?(kc) && File.directory?(staged)
        File.rename(staged, kc)
        return
      end

      u = user_data_root || begin
        t = defined?(Sketchup) ? "sketchup_#{Sketchup.version.to_s.split('.').first}" : 'sketchup_dev'
        File.join(ENV['APPDATA'].to_s.tr('\\', '/'), 'KorpCraft', t)
      end
      marker = File.join(u, 'update', 'pending_full_update.json')
      return unless File.file?(marker) && File.directory?(staged)

      require 'json'
      require 'digest'
      info = begin
        JSON.parse(File.read(marker))
      rescue StandardError
        nil
      end
      manifest = File.join(staged, 'installation.kcm1')
      ok = info.is_a?(Hash) && File.file?(manifest) &&
           Digest::SHA256.file(manifest).hexdigest == info['staged_manifest_sha256']

      if ok
        require 'fileutils'
        FileUtils.rm_rf(prev)
        File.rename(kc, prev) if File.directory?(kc)
        File.rename(staged, kc)
      end
      File.delete(marker)
    rescue StandardError
      nil
    end
  end
end
