#!/usr/bin/env python
import ConfigParser
import optparse
import os
import sys
import urlparse
try:
  from zope.pagetemplate.pagetemplatefile import PageTemplateFile
except:
  print """Unable to import PageTemplateFile.  This probably means
that you need to add ~zope/lib/python to your python path.
Try 'export PYTHONPATH=$PYTHONPATH:/path/to/Zope/lib/python'
where the Zope in question is version 2.8+ (you can use CacheFu
for Zope 2.7 also, but you need Zope 2.8 to run makeconfig.py)"""
  sys.exit(1)

class PT(PageTemplateFile):
  def pt_getContext(self, args, kwargs):
    rval = PageTemplateFile.pt_getContext(self, args=args)
    kwargs.update(rval)
    return kwargs

def unique_values(values):
    d = {}
    for v in values:
        d[v] = 1
    return d.keys()
    
def getContext(config_file):
  c = ConfigParser.ConfigParser()
  c.read(config_file)
  values = {
    'unique_values': unique_values, # helper function
    'hostname': c.get('host', 'name'),
    'python_binary': c.get('python', 'binary'),
    'squid_version': c.get('squid', 'version'),
    'squid_binary': c.get('squid', 'binary'),
    'squid_user': c.get('squid', 'user'),
    'squid_config_dir': c.get('squid', 'config_dir'),
    'squid_log_dir': c.get('squid', 'log_dir'),
    'squid_cache_dir': c.get('squid', 'cache_dir'),
    'squid_cache_size_mb': c.getint('squid', 'cache_size_mb'),
    'squid_direct': c.getboolean('squid', 'direct'),
    'squid_address': c.get('squid', 'address'),
    'squid_port': c.getint('squid', 'port'),
    'squid_admin_email': c.get('squid', 'admin_email')
    }
  protocol_port_map = {}
  section = 'supported-protocols'
  for o in c.options(section):
    protocol_port_map[o] = c.getint(section, o)
  values['protocol_port_map'] = protocol_port_map
  host_zope_map = {}
  section = 'accelerated-hosts'
  for o in c.options(section):
    v = c.get(section,o)
    (proto, host, path, param, query, frag) = urlparse.urlparse('http://' + v)
    sp = host.split(':')
    if len(sp) != 2:
      raise RuntimeError, 'Invalid host:port for accelerated host %s' % v
    host = sp[0]
    port = sp[1]
    host_zope_map[o] = {'zope_host':host, 'zope_port':port, 'zope_path':path}
  values['host_zope_map'] = host_zope_map
  return values

def generate(context, target_dir=None, source_dir=None):
  for fn in os.listdir(source_dir):
    # skip directories (e.g. .svn)
    if not os.path.isfile(os.path.join(source_dir, fn)):
      continue
    # skip emacs tmp files
    if fn.endswith('~') or fn.endswith('#'):
      continue
    if fn == 'httpd.conf' and context.get('squid_direct'):
      continue
    filename = os.path.join(source_dir, fn)
    
    pt = PT(os.path.join(source_dir, filename))
    outfile = os.path.join(target_dir, fn)
    print 'Generating %s' % outfile
    f = open(outfile, 'w+')
    f.write(pt(**context))
    f.close()
  os.chmod(os.path.join(target_dir, 'deploy'), 0700)
  os.chmod(os.path.join(target_dir, 'purge_squid'), 0700)
  os.chmod(os.path.join(target_dir, 'iRedirector.py'), 0700)
  os.chmod(os.path.join(target_dir, 'squidAcl.py'), 0700)

if __name__ == '__main__':
  p = optparse.OptionParser()
  p.add_option('-c', '--config', action='store', dest='config_file')
  p.add_option('-t', '--templates', action='store', dest='template_dir')
  p.add_option('-o', '--output', action='store', dest='output_dir')
  opt, args = p.parse_args()

  config_file = opt.config_file
  if not config_file:
    config_file = raw_input('Configuration file [squid.cfg]: ')
    if not config_file:
      config_file = 'squid.cfg'
  if not os.path.exists(config_file):
    p.error('Unable to read configuration file %s' % config_file)

  template_dir = opt.template_dir
  if not template_dir:
    template_dir = raw_input('Template directory [templates]: ')
    if not template_dir:
      template_dir = 'templates'
  if not template_dir.startswith('/'):
    template_dir = os.path.join(os.getcwd(),template_dir)
  template_dir = os.path.normpath(template_dir)
  if not os.path.exists(template_dir):
    p.error('Unable to find template directory %s' % template_dir)
  if not os.path.isdir(template_dir):
    p.error('%s is not a directory' % template_dir)

  output_dir = opt.output_dir
  if not output_dir:
    output_dir = raw_input('Output directory [output]: ')
    if not output_dir:
      output_dir = 'output'
  if not output_dir.startswith('/'):
    output_dir = os.path.join(os.getcwd(), output_dir)
  output_dir = os.path.normpath(output_dir)
  if not os.path.exists(output_dir):
    d = os.path.dirname(output_dir)
    if not os.path.exists(output_dir):
      if not os.path.exists(d):
        p.error('Unable to open parent directory for output files %s' % d)
      os.mkdir(output_dir)

  context = getContext(config_file)
  if context['squid_direct']:
    print 'Generating files for standalone squid'
  else:
    print 'Generating files for squid behind apache'
  generate(context, output_dir, template_dir)
