#!/usr/bin/env ruby
# frozen_string_literal: true

# SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
# SPDX-FileCopyrightText: 2021 Harald Sitter <sitter@kde.org>

# Generates timezone tables out of tzdata.zi backing data such that the pretty names may be translated.

require 'erb'
require 'ostruct'

# Wraps template rendering. Templating is implemented using the ERB template system.
class Template
  def self.render(context)
    erb = ERB.new(File.read("#{__dir__}/timezonesi18n_generated.h.erb"))
    erb.result(context.instance_eval { binding })
  end
end

# Context object for template rendering. Inside the template file anything defined in here may be used.
# For simplicity's sake continents and cities are not modeled as fully functional objects but rather use
# this context wrapper. Slightly less code.
class RenderContext < OpenStruct
  def initialize(continents:)
    super
  end

  def continent_description(_continent)
    'This is a continent/area associated with a particular timezone'
  end

  # prettify continent name
  def to_contient_name(continent)
    continent # leave unchanged, they are all lovely
  end
end

raise 'tzdata.zi missing, your tzdata was possibly built without' unless File.exist?('/usr/share/zoneinfo/tzdata.zi')

data = File.read('/usr/share/zoneinfo/tzdata.zi')

continents = []
data.split("\n").each do |line|
  line = line.strip
  next if line[0] == '#' # comment

  # zi files have a tricky format. only look at lines that make sense for us (Zone entries and Link entries)
  is_zone = line[0].downcase == 'z'
  is_link = line[0].downcase == 'l'
  next unless is_zone || is_link

  line_parts = line.split(' ')

  # Since we have 2 line formats, the location of the timezone is different in each
  tz = is_zone ? line_parts[1] : line_parts[2]
  parts = tz.split('/')

  # some links are fishy single names we can't use (e.g. `L Europe/Warsaw Poland`)
  next if parts.size < 2

  continent = parts[0]

  # some links also have fake continent values (e.g. `L America/Denver SystemV/MST7MDT`) followed by regions therein
  next if %w[systemv us etc canada brazil mexico chile].any? { |x| x == continent.downcase }

  continents << continent
end


continents = continents.sort_by(&:downcase).uniq

data = Template.render(RenderContext.new(continents: continents))
File.write("#{__dir__}/timezonesi18n_generated.h", data)
