#!/usr/bin/env python

"""
TODO: more docs here
"""

import ConfigParser
import logging
from optparse import OptionParser
import os
import sys

import simpleparse
import yaml

from config_minilang import config_grammar
from config_minilang.config_loader import ConfigLoader

def initialize_logging(logger_name='config_parser'):
    log = logging.getLogger(logger_name)
    log_level = logging.WARNING

    log.setLevel(log_level)
    handler = logging.StreamHandler()
    # send on everything
    handler.setLevel(logging.NOTSET)
    log_format = "%(asctime)s - %(levelname)s: %(message)s"
    handler.setFormatter(logging.Formatter(log_format))
    log.addHandler(handler)

    return log
    
def initialize_options(usage=None):
    cfg = os.path.join(os.environ['HOME'], '.config_parser.cfg') 
    parser = OptionParser()

    parser.set_usage(usage)
    parser.set_defaults(config_file=cfg)
    parser.add_option("-f", "--cfg_file", action="store", type="string",
		      dest="config_file", 
		      help='Config file, default: $HOME/.config_parser.cfg')
    parser.add_option("-d", dest="debug", action="store_true",
                      help="Print debugging info.")
    parser.add_option("-v", dest="verbose", action="store_true",
                      help="Print extra logging info.")
    parser.add_option("-q", dest="quiet", action="store_true",
                      help="Print no logging info.")

    return parser

def read_yaml_files(filename):
    config_section = 'file_locations'
    yaml_values = {}

    config = ConfigParser.ConfigParser()

    # default is options are lowercased
    # keep case sensitive because of our var source
    config.optionxform = str

    if filename not in config.read(filename):
	log.warning("Error reading config file %s, skipping." % filename)
	return yaml_values

    if not config.has_section(config_section):
	log.warning("No section %s in config file, skipping." % 
	            config_section)
	return yaml_values

    for tag, yaml_file in config.items(config_section):
	if not yaml_file.startswith(os.sep):
	    file_dir = os.path.dirname(os.path.realpath(filename))
	    yaml_file = os.path.join(file_dir, yaml_file)

	try: 
	    with open(yaml_file) as f:
		values_dict = yaml.load(f)
		yaml_values[tag] = values_dict	

	    log.info("Loaded YAML file, tag: %s, file: %s" %
		      (tag, yaml_file))
	except IOError as e: 
	    log.error("Error parsing YAML file: %s" % e)
		
    return yaml_values	    	

    # mako expirementation - can't seem to get at myfilter correctly
    # might need to make separate class with myfilter() in it
#def myfilter(string_to_parse):
#    parser.parse(string_to_parse, processor=loader)
#    return loader.value 

class MyFilter():

    loader = None
    env_vars = None
    parser = None

    def __init__(self, loader=loader, parser=parser):
	self.loader = loader
	self.parser = parser

    def myfilter(self, string):
	self.parser.parse(string, processor=self.loader)
	return self.loader.value

if __name__ == '__main__':

    cli_options = initialize_options("usage: %prog [options] template_file [extra_variables]")

    (options, args) = cli_options.parse_args()
    if len(args) < 1:
	cli_options.error("No file to parse given.")

    log = initialize_logging(logger_name=sys.argv[0])

    if options.debug:
	log.setLevel(logging.DEBUG)
    if options.verbose:
	log.setLevel(logging.INFO)
    if options.quiet:
	log.setLevel(logging.ERROR)

    template_dir, template_file = os.path.split(args[0])

    yaml_values = read_yaml_files(options.config_file)

    extra_variables = None
    if len(args) == 2:
	extra_variables = [ args[1] ]
    else:
	extra_variables = sys.stdin.readlines()

    for line in extra_variables:
	variables = line.rstrip().split(',')
	for var in variables:
	    key, value = var.split('=')
	    yaml_values[key] = value
    
    parser = simpleparse.parser.Parser(config_grammar.config_minilang, 
	                               'root')
    loader = ConfigLoader(log=log, env_vars=yaml_values)

    # jinja2 expirementation
    mf = MyFilter(parser=parser, loader=loader)

    from jinja2 import Template, Environment, FileSystemLoader

    env = Environment(loader=FileSystemLoader(template_dir))
    env.filters['myfilter'] = mf.myfilter
    template = env.get_template(template_file)

    print template.render()

    # end jinja2 block



    # mako expirementation - can't seem to get at myfilter correctly
    # might need to make separate class with myfilter() in it
    #from mako.template import Template
    #from mako import exceptions
    #import myfilter

    #try: 
#	mytemplate = Template(filename=template_file,
#			      default_filters=['myfilter'],
#			      imports=['import myfilter'])
#	print mytemplate.render()
#    except:
#	print exceptions.text_error_template().render()
