import os
import sys
from codecs import open

from grammar_compiler_visitor import GrammarCompilerVisitor
from hutnparser import Parser
from meta_grammar import Grammar


def dump(obj, nested_level=0, output=sys.stdout):
    spacing = '   '
    if type(obj) == dict:
        print >> output, '%s{' % ((nested_level) * spacing)
        for k, v in obj.items():
            if hasattr(v, '__iter__'):
                print >> output, '%s%s:' % ((nested_level + 1) * spacing, k)
                dump(v, nested_level + 1, output)
            else:
                print >> output, '%s%s: %s' % ((nested_level + 1) * spacing, k, v)
        print >> output, '%s}' % (nested_level * spacing)
    elif type(obj) == list:
        print >> output, '%s[' % ((nested_level) * spacing)
        for v in obj:
            if hasattr(v, '__iter__'):
                dump(v, nested_level + 1, output)
            else:
                print >> output, '%s%s' % ((nested_level + 1) * spacing, v)
        print >> output, '%s]' % ((nested_level) * spacing)
    else:
        print >> output, '%s%s' % (nested_level * spacing, obj)


def read(n, *args):
  CUR_PATH = os.path.split(__file__)[0]
  with open(os.path.join(CUR_PATH, n), *args, encoding='utf-8') as f:
    return f.read()

def loader(inputfile = './grammars/examples/meta_grammar.g', grammarfile = './grammars/examples/meta_grammar.g'):
    grammar = Grammar()

#    out1 = open('previous.rules', 'w')
#    dump(grammar.rules, 0, out1)
#    out2 = open('previous.tokens', 'w')
#    dump(grammar.tokens, 0, out2)

    result = parser = Parser(grammar, hide_implicit = True).parse(read(grammarfile))
    if(not result['status'] == Parser.Constants.Success):
        print 'not a valid grammar!'
        print result
        return
    
    tree = result['tree']
    visitor = GrammarCompilerVisitor()
    structure = visitor.visit(tree)            
    grammar.rules = structure['rules']
    grammar.tokens = structure['tokens']        

#    out3 = open('after.rules', 'w')
#    dump(structure['rules'], 0, out3)
#    out4 = open('after.tokens', 'w')
#    dump(structure['tokens'], 0, out4)

    result = parser = Parser(grammar, hide_implicit = True).parse(read(inputfile))
    if(not result['status'] == Parser.Constants.Success):
        print 'not a valid input file!'
        print result
        return

    Parser.DefaultPrinter().visit(result['tree'])
    Parser.PrettyPrinter().visit(result['tree'])


if __name__ == "__main__":
    if(len(sys.argv) == 3):
        fileName = sys.argv[1]
        loader(sys.argv[1], sys.argv[2])
    else:
        loader()
