module Mtx::IANALanguageSubtagRegistry
  @@registry_mutex      = Mutex.new
  @@registry            = nil
  @@registry_downloaded = false
  @@registry_file       = "language-subtag-registry"

  def self.fetch_registry
    @@registry_mutex.synchronize {
      return @@registry if @@registry

      if !FileTest.exists?(@@registry_file)
        url = "https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry"
        runq "wget", url, "wget --quiet -O #{@@registry_file} #{url}"
        @@registry_downloaded = true
      end

      @@registry = {}
      entry      = {}
      process    = lambda do
        type = entry.delete(:type)

        if type
          @@registry[type] ||= []
          @@registry[type]  << entry
        end

        entry = {}
      end

      IO.readlines(@@registry_file).
        map(&:chomp).
        each do |line|

        if line == '%%'
          process.call

        elsif %r{^(Type|Subtag|Description): *(.+)}i.match(line)
          entry[$1.downcase.to_sym] = $2

        elsif %r{^Prefix: *(.+)}i.match(line)
          entry[:prefix] ||= []
          entry[:prefix]  << $1
        end
      end

      process.call
    }

    return @@registry
  end

  def self.do_create_cpp entries
    cpp_file_name   = "src/common/iana_language_subtag_registry_list.cpp"
    entry_formatter = lambda do |entry|
      if entry[:prefix]
        prefix = 'VS{ ' + entry[:prefix].sort.map(&:to_cpp_string).join(', ') + ' }'
      else
        prefix = 'VS{}'
      end

      [ entry[:subtag].downcase.to_cpp_string,
        entry[:description].to_u8_cpp_string,
        prefix,
      ]
    end

    formatter = lambda do |type, name|
      rows = entries[type].map(&entry_formatter)

      "  g_#{name}.reserve(#{entries[type].size});\n\n" +
        format_table(rows.sort, :column_suffix => ',', :row_prefix => "  g_#{name}.emplace_back(", :row_suffix => ");").join("\n") +
        "\n"
    end

    formatted = [
      formatter.call("extlang", "extlangs"),
      formatter.call("variant", "variants"),
    ]

    header = <<EOT
/*
   mkvmerge -- utility for splicing together matroska files
   from component media subtypes

   Distributed under the GPL v2
   see the file COPYING for details
   or visit https://www.gnu.org/licenses/old-licenses/gpl-2.0.html

   IANA language subtag registry

   Written by Moritz Bunkus <moritz@bunkus.org>.
*/

// ----------------------------------------------------------------------------------------------
// NOTE: this file is auto-generated by the "dev:iana_language_subtag_registry_list" rake target.
// ----------------------------------------------------------------------------------------------

#include "common/common_pch.h"

#include "common/iana_language_subtag_registry.h"

namespace mtx::iana::language_subtag_registry {

std::vector<entry_t> g_extlangs, g_variants;

using VS = std::vector<std::string>;

void
init() {
EOT

    footer = <<EOT
}

} // namespace mtx::iana::language_subtag_registry
EOT

    content = header +
      formatted.join("\n") +
      footer

    runq("write", cpp_file_name) { IO.write("#{$source_dir}/#{cpp_file_name}", content); 0 }
  end

  def self.create_cpp
    do_create_cpp(self.fetch_registry)
  end

  END {
    File.unlink(@@registry_file) if @@registry_downloaded && FileTest.exists?(@@registry_file)
  }
end
