#! /usr/bin/env python

###################################################
# Convert each worldflags picture to a PDF file.  #
#                                                 #
# In fact, this script creates only a Ninja       #
# build file to perform the conversion and a      #
# fakeworldflags.sty file that uses the           #
# generated PDF files.                            #
#                                                 #
# Author: Scott Pakin <scott-clsl@pakin.org>      #
###################################################

import glob
import os
import re
import subprocess
import sys
import textwrap


def kpsewhich(fname, must_exist=True):
    'Find a filename in the TeX tree.'
    proc = subprocess.run(['kpsewhich', fname], capture_output=True,
                          check=must_exist, encoding='utf-8')
    if proc.returncode != 0:
        return None
    return proc.stdout.strip()


# If worldflags.sty doesn't exist, write a dummy worldflags.ninja and exit.
sty = kpsewhich('worldflags.sty', must_exist=False)
if sty is None:
    with open('worldflags.ninja', 'w') as w:
        # Write some boilerplate code.
        w.write('# This is a generated file.  DO NOT EDIT.\n')
        w.write('# Edit %s instead.\n' % os.path.abspath(sys.argv[0]))
        w.write('''
rule touch
  command = touch $out

build fakeworldflags.sty : touch

build WORLDFLAGS : phony fakeworldflags.sty
''')
    sys.exit(0)


# Extract the package date from worldflags.sty.
wfdate_re = re.compile(r'(\d\d\d\d)-(\d\d)-(\d\d)')
with open(sty) as r:
    for ln in r:
        match = wfdate_re.search(ln)
        if match is not None:
            wfdate = match[1] + '/' + match[2] + '/' + match[3]
            break

# Acquire a list of all defined symbols.
wfdir = os.path.dirname(kpsewhich('worldflag_US.tex'))
tex_files = glob.glob(os.path.join(wfdir, '*.tex'))
flags = [os.path.splitext(os.path.basename(fn))[0][10:] for fn in tex_files]
flags.sort()

# Generate a Ninja build file for managing PDF creation.
with open('worldflags.ninja', 'w') as w:
    # Write some boilerplate code.
    w.write('# This is a generated file.  DO NOT EDIT.\n')
    w.write('# Edit %s instead.\n' % os.path.abspath(sys.argv[0]))
    w.write(r'''
rule write-file
  command = /bin/echo -e '$body' > $out
  description = Creating $out

build worldflags/preloaded.tex : write-file
  body = $
    \\documentclass{minimal}\n$
    \\usepackage{worldflags}\n$
    \\begin{document}\n$
    \\end{document}

rule generate-mylatex
  command = $
    cd worldflags ; $
    pdflatex --ini '&pdflatex' mylatex.ltx preloaded.tex
  description = Creating mylatex.fmt for faster builds

''')
    w.write('build worldflags/mylatex.fmt worldflags/mylatex.log :'
            ' generate-mylatex worldflags/preloaded.tex | %s %s\n' %
            (kpsewhich('mylatex.ltx'), kpsewhich('worldflags.sty')))
    w.write(r'''
rule write-symbol-tex
  command = bash -c '$
    base=$$(basename $out .tex) ; $
    sym=$${base:5} ; $
    echo -e "$
    \\\\documentclass{minimal}\\n$
    \\\\begin{document}\\n$
    \\\\worldflag[width=9pt]{$$sym}\\n$
    \\\\end{document}" > $out'
      description = Writing $out

''')

    # For each symbol defined by worldflags.sty, create a LaTeX file.
    for abbr in flags:
        w.write(f'build worldflags/flag_{abbr}.tex : write-symbol-tex\n')

    # Compile each LaTeX file to a PDF file.
    w.write(r'''
rule tex-to-pdf
  command = $
    texname="$$(basename $in)" ; $
    jname="$$(basename $in .tex)-uncrop" ; $
    cd worldflags ; $
    pdflatex -jobname "$$jname" '&mylatex' "$$texname"
  description = pdflatex $in

''')
    for abbr in flags:
        base = 'flag_' + abbr
        w.write(f'build worldflags/{base}-uncrop.pdf worldflags/{base}-uncrop.log worldflags/{base}-uncrop.aux : tex-to-pdf worldflags/{base}.tex | worldflags/mylatex.fmt\n')
    w.write('\n')

    # Crop each PDF file.
    w.write('rule crop-pdf\n')
    w.write('  command = pdfcrop $in $out\n')
    w.write('  description = Cropping $in to produce $out\n\n')
    for abbr in flags:
        base = 'flag_' + abbr
        w.write(f'build worldflags/{base}.pdf : crop-pdf worldflags/{base}-uncrop.pdf\n')

    # Create a fakeworldflags.sty file.
    w.write(r'''
build fakeworldflags.sty : write-file
  body = $
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n$
    % This is a generated file.  DO NOT EDIT. %\n$
    % Edit makefakeworldflags instead.        %\n$
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n$
    \n$
''')
    w.write(r'''
    \\NeedsTeXFormat{LaTeX2e}\n$
    \\ProvidesPackage{fakeworldflags}[%s v0.0 Flags of the world]\n$
    \\RequirePackage{graphicx}\n$
    \n$
    \\newcommand*{\worldflag}[1]{\\includegraphics{worldflags/flag_#1}}\n$
    \n$
    \\endinput
'''[1:] % wfdate)
    w.write('\n')

    # Create a phony symbol that depends on fakeworldflags.sty and all
    # generated PDF files.
    w.write('build WORLDFLAGS : phony $\n')
    phony = [f'worldflags/flag_{abbr}.pdf' for abbr in flags] + \
        ['fakeworldflags.sty']
    lines = textwrap.wrap(' '.join(phony),
                          break_long_words=False, break_on_hyphens=False,
                          initial_indent='  ', subsequent_indent='  ')
    w.write('%s\n' % ' $\n'.join(lines))
