#!/usr/bin/env ruby
#
# y2metainfo - Automatically generate appstream data for YaST modules based on
# their desktop files
# Based on upstream appstream spec:
# https://www.freedesktop.org/wiki/Distributions/AppStream/
#
# Fixes: https://features.opensuse.org/319035
#
# Author: Stasiek Michalski <hellcp@opensuse.org>
# Copyright 2019
#

require "rexml/document"
require "optparse"

options = {}

OptionParser.new do |parser|
  parser.banner = "Usage: y2metainfo [options]"
  parser.on("-h", "--help", "Show this help message") do
    puts parser
  end
  parser.on("-f", "--file FILEPATH", "The desktop file of the module") do |v|
    options[:file] = v
  end
  parser.on("-l", "--license LICENSE", "The license of the module") do |v|
    options[:license] = v
  end
  parser.on("-o", "--output DIRECTORY", "The output directory") do |v|
    options[:output] = v
  end
  parser.on("-u", "--url URL", "The project url") do |v|
    options[:url] = v
  end
  parser.on("-v", "--version VERSION", "Current version of the component") do |v|
    options[:version] = v
  end
end.parse!

def metainfo_gen(desktop, license, url, version)
  output = ""
  xml = REXML::Document.new
  xml << REXML::XMLDecl.new("1.0", "UTF-8")
  base = xml.add_element("component", "type" => "addon", "xmlns" => "https://specifications.freedesktop.org/metainfo/1.0")

  file = File.open(desktop).read
  data = Hash[file.scan(/(.*)?=\s*?(.*)/).map { |k,v| [k.strip, v.strip] }]
  base.add_element("id").add_text(File.basename(desktop))
  # Exectutes based on id of desktop file https://www.freedesktop.org/software/appstream/docs/chap-Metadata.html#tag-launchable
  base.add_element("launchable", "type" => "desktop-id").add_text(File.basename(desktop))
  data.select{ |x| x.start_with?("GenericName") }.each do |key, value|
    name = base.add_element("name").add_text(value)
    lang = (/(?<=\[).*(?=\])/).match(key)
    name.add_attribute("xml:lang", lang) if lang
  end
  data.select{ |x| x.start_with?("Comment") }.each do |key, value|
    name = base.add_element("summary").add_text(value)
    lang = (/(?<=\[).*(?=\])/).match(key)
    name.add_attribute("xml:lang", lang) if lang
  end
  cat = base.add_element("categories")
  rejected_categories = ["Settings", "ConsoleOnly", "DesktopSettings"]
  categories = data["Categories"].split(";") - rejected_categories
  categories.each do |category|
    cat.add_element("category").add_text(category)
  end
  rel = base.add_element("releases")
  rel.add_element("release").add_attribute("version", version)
  if data["Mimetype"]
    mime = base.add_element("mimetypes")
    data["Mimetype"].split(";").each do |mimetype|
      mime.add_element("mimetype").add_text(mimetype)
    end
  end
  if license
    base.add_element("metadata_license").add_text(license)
    base.add_element("project_license").add_text(license)
  end
  base.add_element("extends").add_text("org.opensuse.YaST.desktop")
  if url
    base.add_element("url", "type" => "homepage").add_text(url)
  else
    base.add_element("url", "type" => "homepage").add_text("https://yast.opensuse.org")
  end
  base.add_element("url", "type" => "bugtracker").add_text("https://bugzilla.opensuse.org")
  base.add_element("update_contact").add_text("yast-devel@opensuse.org")

  formatter = REXML::Formatters::Pretty.new(2)
  formatter.compact = true
  formatter.write(xml, output)
  output
end

result = metainfo_gen(options[:file], options[:license], options[:url], options[:version])
if options[:output] && options[:file]
  filename = options[:output] + File.basename(options[:file], ".desktop") + ".metainfo.xml"
  File.write(filename, result)
elsif options[:file]
  puts result
end
