#!/usr/bin/python

import plyproto.model as m
import pdb
import argparse
import plyproto.parser as plyproto
import traceback
import sys
import jinja2
import os
from xos2jinja import XOS2Jinja
from proto2xproto import Proto2XProto

import lib

parse = argparse.ArgumentParser(description='XOS code generator')
parse.add_argument('--rev', dest='rev', action='store_true',default=False, help='Convert proto to xproto')
parse.add_argument('--input', dest='input', action='store',default=None, help='Filename in Protobufs')
parse.add_argument('--target', dest='target', action='store',default=None, help='Output format, corresponding to <output>.yaml file')
parse.add_argument('--output', dest='output', action='store',default=None, help='Destination path')
parse.add_argument('--attic', dest='attic', action='store',default=None, help='The location at which static files are stored')
parse.add_argument('--kvpairs', dest='kv', action='store',default=None, help='Key value pairs to make available to the target')

args = parse.parse_args()

def file_exists(name):
    return (os.path.exists(args.attic+'/'+name))

def include_file(name):
    return open(args.attic+'/'+name).read()
    # FIXME: Support templates in the future
    #return jinja2.Markup(loader.get_source(env, name)[0])

loader = jinja2.PackageLoader(__name__, 'templates')
env = jinja2.Environment(loader=loader)

def main():
    try:
        if (not args.rev):
            v = XOS2Jinja()
        else:
            v = Proto2XProto()

        parser = plyproto.ProtobufAnalyzer()
        input = open(args.input).read()

        ast = parser.parse_string(input,debug=0)
        ast.accept(v)
        
        template_name = os.path.abspath(args.target)

	os_template_loader = jinja2.FileSystemLoader( searchpath=[os.path.split(template_name)[0]])
        os_template_env = jinja2.Environment(loader=os_template_loader)
        os_template_env.globals['include_file'] = include_file
        os_template_env.globals['file_exists'] = file_exists

        for f in dir(lib):
            if f.startswith('xproto'):
                os_template_env.globals[f] = getattr(lib, f)

        template = os_template_env.get_template(os.path.split(template_name)[1])
        context = {}

        try:
            for s in args.kv.split(','):
                k,val=s.split(':')
                context[k]=val
        except:
            pass

        rendered = template.render({"proto": {'messages':v.messages},"context":context})

        lines = rendered.splitlines()
        current_buffer = []
        for l in lines:
            if (l.startswith('+++')):
                prefixes = args.output.rsplit('/',1)
                if (len(prefixes)>1):
                    path = prefix+'/'+l[4:]
                    direc = prefix
                    os.system('mkdir -p %s'%direc)
                else:
                    path = l[4:]
                
                fil = open(path,'w')
                buf = '\n'.join(current_buffer)

                obuf = buf

                """
                for d in options.dict:
                    df = open(d).read()
                    d = json.loads(df)

                    pattern = re.compile(r'\b(' + '|'.join(d.keys()) + r')\b')
                    obuf = pattern.sub(lambda x: d[x.group()], buf)
                """

                fil.write(obuf)
                fil.close()

                print 'Written to file %s'%path
                current_buffer = []
            else:
                current_buffer.append(l)

        if (current_buffer):
            print '\n'.join(current_buffer)


    except Exception as e:
        print "    Error occurred! file[%s]" % (args.input), e
        print '-'*60
        traceback.print_exc(file=sys.stdout)
        print '-'*60
        exit(1)

if __name__=='__main__':
    main()
