#!/usr/bin/env python3
'''Take values from a config file and fill them into a set of templates.
Write the result to the current directory.'''

import os, sys, re, shutil
import argparse

def file_newer(path_a, than_path_b):
  return os.path.getmtime(path_a) > os.path.getmtime(than_path_b)

LAST_LOCAL_CONFIG_FILE = '.last_config'
LAST_TMPL_DIR = '.last_templates'

parser = argparse.ArgumentParser(description=__doc__,
                                 formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument('sources', metavar='SRC', nargs='*',
                    help='Pass both a template directory and a config file.')
parser.add_argument('-s', '--check-stale', dest='check_stale', action='store_true',
                    help='only verify age of generated files vs. config and templates.'
                    ' Exit nonzero when any source file is newer. Do not write anything.')

args = parser.parse_args()

local_config_file = None
tmpl_dir = None

for src in args.sources:
  if os.path.isdir(src):
    if tmpl_dir is not None:
      print('Error: only one template dir permitted. (%r vs. %r)' % (tmpl_dir, src))
    tmpl_dir = src
  elif os.path.isfile(src):
    if local_config_file is not None:
      print('Error: only one config file permitted. (%r vs. %r)' % (local_config_file, src))
    local_config_file = src

if local_config_file is None and os.path.isfile(LAST_LOCAL_CONFIG_FILE):
  local_config_file = open(LAST_LOCAL_CONFIG_FILE).read().strip()

if tmpl_dir is None and os.path.isfile(LAST_TMPL_DIR):
  tmpl_dir = open(LAST_TMPL_DIR).read().strip()

if not tmpl_dir or not os.path.isdir(tmpl_dir):
  print("Template dir does not exist: %r" % tmpl_dir)
  exit(1)

if not local_config_file or not os.path.isfile(local_config_file):
  print("No such config file: %r" % tmpl_dir)
  exit(1)

local_config_file = os.path.realpath(local_config_file)
tmpl_dir = os.path.realpath(tmpl_dir)

print('using config file %r\non templates %r' % (local_config_file, tmpl_dir))

with open(LAST_LOCAL_CONFIG_FILE, 'w') as last_file:
  last_file.write(local_config_file)
with open(LAST_TMPL_DIR, 'w') as last_file:
  last_file.write(tmpl_dir)

# read in variable values from config file
local_config = {}

line_nr = 0
for line in open(local_config_file):
  line_nr += 1
  line = line.strip('\n')

  if line.startswith('#'):
    continue

  if not '=' in line:
    if line:
      print("Error: %r line %d: %r" % (local_config_file, line_nr, line))
      exit(1)
    continue

  split_pos = line.find('=')
  name = line[:split_pos]
  val = line[split_pos + 1:]

  if val.startswith('"') and val.endswith('"'):
    val = val[1:-1]

  if name in local_config:
    print("Error: duplicate identifier in %r line %d: %r" % (local_config_file, line_nr, line))
  local_config[name] = val

# replace variable names with above values recursively
replace_re = re.compile('\$\{([A-Za-z0-9_]*)\}')
command_re = re.compile('\$\{([A-Za-z0-9_]*)\(([^)]*)\)\}')

idx = 0

def check_stale(src_path, target_path):
  if file_newer(src_path, target_path):
    print('Stale: %r is newer than %r' % (src_path, target_path))
    exit(1)

for tmpl_name in sorted(os.listdir(tmpl_dir)):

  # omit "hidden" files
  if tmpl_name.startswith('.'):
    continue

  tmpl_src = os.path.join(tmpl_dir, tmpl_name)
  dst = tmpl_name

  if args.check_stale:
    check_stale(local_config_file, dst)
    check_stale(tmpl_src, dst)

  local_config['_fname'] = tmpl_name
  local_config['_name'] = os.path.splitext(tmpl_name)[0]
  local_config['_idx0'] = str(idx)
  idx += 1
  local_config['_idx1'] = str(idx)

  try:
    result = open(tmpl_src).read()
  except:
    print('Error in %r' % tmpl_src)
    raise

  while True:
    used_vars = set()
    for m in command_re.finditer(result):
      cmd = m.group(1)
      arg = m.group(2)
      if cmd == 'include':
        include_path = os.path.join(tmpl_dir, arg)
        if not os.path.isfile(include_path):
          print('Error: included file does not exist: %r in %r' % (include_path, tmpl_src))
          exit(1)
        try:
          incl = open(include_path).read()
        except:
          print('Cannot read %r for %r' % (include_path, tmpl_src))
          raise
        if args.check_stale:
          check_stale(include_path, dst)
        result = result.replace('${%s(%s)}' % (cmd, arg), incl)
      else:
        print('Error: unknown command: %r in %r' % (cmd, tmpl_src))
        exit(1)

    for m in replace_re.finditer(result):
      name = m.group(1)
      if not name in local_config:
        print('Error: undefined var %r in %r' % (name, tmpl_src))
        exit(1)
      used_vars.add(name)

    if not used_vars:
      break

    for var in used_vars:
      result = result.replace('${%s}' % var, local_config.get(var))

  if not args.check_stale:
    with open(dst, 'w') as dst_file:
      dst_file.write(result)
    shutil.copymode(tmpl_src, dst)

# vim: ts=2 sw=2 expandtab
