class Selenium::WebDriver::Firefox::Extension

def applications_gecko_id(manifest)

def applications_gecko_id(manifest)
  manifest.dig('applications', 'gecko', 'id')&.strip
end

def create_root

def create_root
  if File.directory? @path
    @path
  else
    unless Zipper::EXTENSIONS.include? File.extname(@path)
      raise Error::WebDriverError, "expected #{Zipper::EXTENSIONS.join(' or ')}, got #{@path.inspect}"
    end
    @should_reap_root = true
    Zipper.unzip(@path)
  end
end

def initialize(path)

def initialize(path)
  raise Error::WebDriverError, "could not find extension at #{path.inspect}" unless File.exist?(path)
  @path             = path
  @should_reap_root = false
end

def name_and_version(manifest)

def name_and_version(manifest)
  [manifest['name'].delete(' '), manifest['version']].join('@')
end

def read_id(directory)

def read_id(directory)
  read_id_from_install_rdf(directory) || read_id_from_manifest_json(directory)
end

def read_id_from_install_rdf(directory)

def read_id_from_install_rdf(directory)
  rdf_path = File.join(directory, 'install.rdf')
  return unless File.exist?(rdf_path)
  doc = REXML::Document.new(File.read(rdf_path))
  namespace = doc.root.namespaces.key(NAMESPACE)
  if namespace
    id_node = REXML::XPath.first(doc, "//#{namespace}:id")
    return id_node.text if id_node
    attr_node = REXML::XPath.first(doc, "//@#{namespace}:id")
    return attr_node.value if attr_node
  end
  raise Error::WebDriverError, "cannot locate extension id in #{rdf_path}"
end

def read_id_from_manifest_json(directory)

def read_id_from_manifest_json(directory)
  manifest_path = File.join(directory, 'manifest.json')
  return unless File.exist?(manifest_path)
  manifest = JSON.parse(File.read(manifest_path))
  applications_gecko_id(manifest) || name_and_version(manifest)
end

def write_to(extensions_dir)

def write_to(extensions_dir)
  root_dir = create_root
  ext_path = File.join extensions_dir, read_id(root_dir)
  FileUtils.rm_rf ext_path
  FileUtils.mkdir_p File.dirname(ext_path), mode: 0o700
  FileUtils.cp_r root_dir, ext_path
  FileReaper.reap(root_dir) if @should_reap_root
end