#!/usr/bin/env python
# -*- coding: utf-8 -*-

# CAVEAT UTILITOR
#
# This file was automatically generated by Grako.
#
#    https://pypi.python.org/pypi/grako/
#
# Any changes you make to it will be overwritten the next time
# the file is generated.


from __future__ import print_function, division, absolute_import, unicode_literals
from grako.parsing import graken, Parser


__version__ = (2014, 12, 11, 12, 59, 52, 3)

__all__ = [
    'samtoolsParser',
    'samtoolsSemantics',
    'main'
]


class samtoolsParser(Parser):
    def __init__(self, whitespace=None, nameguard=True, **kwargs):
        super(samtoolsParser, self).__init__(
            whitespace=whitespace,
            nameguard=nameguard,
            **kwargs
        )

    @graken()
    def _start_(self):
        self._token('samtools')
        self._command_()
        self._check_eof()

    @graken()
    def _command_(self):
        with self._choice():
            with self._option():
                self._samtools_view_()
            with self._option():
                self._samtools_merge_()
            with self._option():
                self._samtools_flagstat_()
            with self._option():
                self._samtools_index_()
            with self._option():
                self._samtools_sort_()
            with self._option():
                self._samtools_empty_()
            self._error('no available options')

    @graken()
    def _samtools_empty_(self):
        pass

    @graken()
    def _samtools_view_(self):
        self._token('view')
        self.ast['command'] = self.last_node

        def block1():
            self._view_option_()
            self.ast['options'] = self.last_node
        self._closure(block1)

        def block4():
            self._bamsamfile_()
        self._closure(block4)
        self.ast['input'] = self.last_node

        self.ast._define(
            ['command', 'options', 'input'],
            []
        )

    @graken()
    def _samtools_merge_(self):
        self._token('merge')
        self.ast['command'] = self.last_node

        def block1():
            self._merge_option_()
            self.ast['options'] = self.last_node
        self._closure(block1)
        self._bamsamfile_()
        self.ast['output'] = self.last_node

        def block5():
            self._bamsamfile_()
        self._positive_closure(block5)

        self.ast['input'] = self.last_node

        self.ast._define(
            ['command', 'options', 'output', 'input'],
            []
        )

    @graken()
    def _samtools_flagstat_(self):
        self._token('flagstat')
        self.ast['command'] = self.last_node
        self._bamsamfile_()
        self.ast['input'] = self.last_node

        self.ast._define(
            ['command', 'input'],
            []
        )

    @graken()
    def _samtools_index_(self):
        self._token('index')
        self.ast['command'] = self.last_node
        self._bamsamfile_()
        self.ast['input'] = self.last_node

        def block3():
            self._anyfile_()
        self._closure(block3)
        self.ast['output'] = self.last_node

        self.ast._define(
            ['command', 'input', 'output'],
            []
        )

    @graken()
    def _samtools_sort_(self):
        self._token('sort')
        self.ast['command'] = self.last_node

        def block1():
            self._sort_option_()
            self.ast['options'] = self.last_node
        self._closure(block1)
        self._bamsamfile_()
        self.ast['input'] = self.last_node

        def block5():
            self._anyfile_()
        self._closure(block5)
        self.ast['output_prefix'] = self.last_node

        self.ast._define(
            ['command', 'options', 'input', 'output_prefix'],
            []
        )

    @graken()
    def _view_option_(self):

        def block0():
            with self._choice():
                with self._option():
                    self._view_argoption_()
                with self._option():
                    self._view_noargoption_()
                self._error('no available options')
        self._closure(block0)

    @graken()
    def _view_argoption_(self):
        self._view_argoptionflag_()
        self._argoptionvalue_()

    @graken()
    def _view_argoptionflag_(self):
        self._pattern(r'-[@LtToRfFqlrs]')

    @graken()
    def _view_noargoption_(self):
        self._pattern(r'-[bhHSu1xXcB]+')

    @graken()
    def _sort_option_(self):

        def block0():
            with self._choice():
                with self._option():
                    self._sort_argoption_()
                with self._option():
                    self._sort_noargoption_()
                self._error('no available options')
        self._closure(block0)

    @graken()
    def _sort_argoption_(self):
        self._sort_argoptionflag_()
        self._argoptionvalue_()

    @graken()
    def _sort_argoptionflag_(self):
        self._pattern(r'-[l@m]')

    @graken()
    def _sort_noargoption_(self):
        self._pattern(r'-[nfo]+')

    @graken()
    def _merge_option_(self):

        def block0():
            with self._choice():
                with self._option():
                    self._merge_argoption_()
                with self._option():
                    self._merge_noargoption_()
                self._error('no available options')
        self._closure(block0)

    @graken()
    def _merge_argoption_(self):
        self._merge_argoptionflag_()
        self._argoptionvalue_()

    @graken()
    def _merge_argoptionflag_(self):
        self._pattern(r'-[l@Rh]+')

    @graken()
    def _merge_noargoption_(self):
        self._pattern(r'-[nruf1]+')

    @graken()
    def _argoptionvalue_(self):
        self._pattern(r'[^ ]+')

    @graken()
    def _bamsamfile_(self):
        self._pattern(r'[^ ]+\.[bs]am')

    @graken()
    def _anyfile_(self):
        self._pattern(r'[^ ]+')


class samtoolsSemantics(object):
    def start(self, ast):
        return ast

    def command(self, ast):
        return ast

    def samtools_empty(self, ast):
        return ast

    def samtools_view(self, ast):
        return ast

    def samtools_merge(self, ast):
        return ast

    def samtools_flagstat(self, ast):
        return ast

    def samtools_index(self, ast):
        return ast

    def samtools_sort(self, ast):
        return ast

    def view_option(self, ast):
        return ast

    def view_argoption(self, ast):
        return ast

    def view_argoptionflag(self, ast):
        return ast

    def view_noargoption(self, ast):
        return ast

    def sort_option(self, ast):
        return ast

    def sort_argoption(self, ast):
        return ast

    def sort_argoptionflag(self, ast):
        return ast

    def sort_noargoption(self, ast):
        return ast

    def merge_option(self, ast):
        return ast

    def merge_argoption(self, ast):
        return ast

    def merge_argoptionflag(self, ast):
        return ast

    def merge_noargoption(self, ast):
        return ast

    def argoptionvalue(self, ast):
        return ast

    def bamsamfile(self, ast):
        return ast

    def anyfile(self, ast):
        return ast


def main(filename, startrule, trace=False, whitespace=None, nameguard=None):
    import json
    with open(filename) as f:
        text = f.read()
    parser = samtoolsParser(parseinfo=False)
    ast = parser.parse(
        text,
        startrule,
        filename=filename,
        trace=trace,
        whitespace=whitespace,
        nameguard=nameguard)
    print('AST:')
    print(ast)
    print()
    print('JSON:')
    print(json.dumps(ast, indent=2))
    print()

if __name__ == '__main__':
    import argparse
    import string
    import sys

    class ListRules(argparse.Action):
        def __call__(self, parser, namespace, values, option_string):
            print('Rules:')
            for r in samtoolsParser.rule_list():
                print(r)
            print()
            sys.exit(0)

    parser = argparse.ArgumentParser(description="Simple parser for samtools.")
    parser.add_argument('-l', '--list', action=ListRules, nargs=0,
                        help="list all rules and exit")
    parser.add_argument('-n', '--no-nameguard', action='store_true',
                        dest='no_nameguard',
                        help="disable the 'nameguard' feature")
    parser.add_argument('-t', '--trace', action='store_true',
                        help="output trace information")
    parser.add_argument('-w', '--whitespace', type=str, default=string.whitespace,
                        help="whitespace specification")
    parser.add_argument('file', metavar="FILE", help="the input file to parse")
    parser.add_argument('startrule', metavar="STARTRULE",
                        help="the start rule for parsing")
    args = parser.parse_args()

    main(
        args.file,
        args.startrule,
        trace=args.trace,
        whitespace=args.whitespace,
        nameguard=not args.no_nameguard
    )

