#!/usr/bin/ruby
# coding: utf-8
class PoStr
  Sections = %w(Headers Source Translated)
  attr_accessor :status, :src, :srcclean, :dest, :prev, :prevclean, :type, :location
  def initialize(text)
    section = 0
    @status = ''
    @src = []
    @dest = []
    @prev = []

    text.split(/\n/).each do |lin|
      # Header
      if section == 0
        if lin =~ /^#(.) ([^:]*)(?::(.*))?/
          type = $1
          field = $2
          value = $3

          @status = 'fuzzy' if type == ',' and field == 'fuzzy'
          @type = value if type == '.' and field == 'type'
          @location = {:file => field, :line => value} if type == ':'
          if type == '|'
            #print lin, "\n"
            if lin =~ /^\#\| msgid "(.*)"$/
              #print "first '%s'\n" % $1
              @prev << $1
            elsif lin =~ /^\#\| "(.*)"$/
              @prev << $1
            end
          end
        elsif lin =~ /^msgid "(.*)"/
          section += 1
          @src << $1
        else
          boom(section, lin, text)
        end

      # Source text
      elsif section == 1
        if lin =~ /^"(.*)"$/
          @src << $1
        elsif lin =~ /^msgstr "(.*)"/
          section += 1
          @dest << $1
        else
          boom(section, lin, text)
        end

      # Translated text
      else
        if lin =~ /^"(.*)"$/
          @dest << $1
        else
          boom(section, lin, text)
        end
      end
    end
  end

  def boom(section, line, text)
    raise RuntimeError, "Unexpected string in %s:\n %s\n\nFull text: %s" %
                        [Sections[section], line, text]
  end

  def fuzzy?
    @status == 'fuzzy'
  end

  def srcstr()
    return @src.join("")
  end

  def deststr()
    return @dest.join("")
  end

  def prevstr()
    return @prev.join("")
  end

  def output()
    # No use outputting empty translations
    if '' == srcstr() && '' == deststr()
      return
    end
    if '' != @type
      print "#. type:%s\n" % [@type]
    end
    if @location
      print "#: %s:%s\n" % [@location[:file], @location[:line]]
    end
    if fuzzy?
      print "#, fuzzy\n"
      if '' != prevstr()
        @prev.each_with_index do |lin, idx|
          if idx == 0
            print "#| msgid \"%s\"\n" % lin
          else
            print "#| \"%s\"\n" % lin
          end
        end
      end
    end
    @src.each_with_index do |lin, idx|
      if idx == 0
        print "msgid \"%s\"\n" % lin
      else
        print "\"%s\"\n" % lin
      end
    end
    @dest.each_with_index do |lin, idx|
      if idx == 0
        print "msgstr \"%s\"\n" % lin
      else
        print "\"%s\"\n" % lin
      end
    end
    print "\n"
  end
end

raise ArgumentError, 'Source file not specified' if ARGV.size != 1
file = ARGV[0]
strings = File.open(file,'r').read.split(/\n\n/)[1..-1].map {|str| PoStr.new(str)}

#print strings

c = 0
strings.each do |entry|
  # Ignore whitespace changes between prev and src
  entry.prevclean = entry.prevstr().gsub(/ +/, ' ')
  entry.srcclean = entry.srcstr().gsub(/ +/, ' ')
    
  if entry.fuzzy?
    if entry.prevclean == entry.srcclean
      entry.status = ''
      #print "# clear fuzzy (space)\n"
      c = c + 1
      entry.output
      next
    end

    # Rewrite title strings, which lost '#' at the front
    if entry.prevclean.gsub(/^#+ +/, '') == entry.srcclean
      # FIXME Not safe to clear fuzzy flag, might have bogus translation
      entry.status = ''
      if entry.dest[0].gsub!(/^#+ +/, '') ||
         ('' == entry.dest[0] && entry.dest[1].gsub!(/^#+ +/, ''))
        #print "cleared fuzzy (title)\n"
        c = c + 1
      end
    end

    # Rewrite footnotes to use "<placeholder type=\"footnote\" id=\"0\"/>"
    if entry.srcclean =~ /<placeholder type=\\"footnote\\" id=\\"0\\"\/>/
      #print "found footnote\n"
      p = entry.prevclean
      p.sub!(/([a-z]\.["”]?)(\d+)(\s)/, "\\1<placeholder type=\\\"footnote\\\" id=\\\"0\\\"\/>\\3")
      p.sub!(/([a-z]\.["”]?)(\d+)$/, "\\1<placeholder type=\\\"footnote\\\" id=\\\"0\\\"\/>")
      #print p, "\n"
      #print entry.src, "\n"
      if p == entry.srcclean
        replaced = false
        entry.dest.each do |part|
          if part.sub!(/([a-z]\.["”»]?)(\d+)(\s)/, "\\1<placeholder type=\\\"footnote\\\" id=\\\"0\\\"\/>\\3")
            replaced = true
          end
        end
        entry.dest.each do |part|
          if part.sub!(/([a-z]\.["”»]?)(\d+)$/, "\\1<placeholder type=\\\"footnote\\\" id=\\\"0\\\"\/>")
            replaced = true
          end
        end
        if replaced
          #print "cleared fuzzy (footnote)\n"
          entry.status = ''
          c = c + 1
        end
      end
    end
  end

  # Copy image references and single URLs unchanged, even for non-fuzzies
  if entry.prevclean =~ /!\[\]\(Pictures\// ||
     entry.srcclean =~ /^<ulink url=\\\".+\\\"\/>$/
    entry.dest = entry.src.clone()
    entry.status = ''
    c = c + 1
  end

  entry.output
end
print "# Cleared %d fuzzy strings\n" % [c]
