#!/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__ = (2015, 1, 2, 21, 49, 31, 4)

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


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

    @graken()
    def _start_(self):
        with self._choice():
            with self._option():
                self._samtools_()
            with self._option():
                self._samtools_00_()
            with self._option():
                self._samtools_01_()
            with self._option():
                self._samtools_02_()
            with self._option():
                self._samtools_03_()
            self._error('no available options')

    @graken()
    def _samtools_(self):
        self._token('samtools')
        self._pattern(r'\s+')
        self._token('view')

        def block0():
            self._pattern(r'\s+')
            self._viewoptions_()
        self._closure(block0)
        self._pattern(r'\s+')
        self._inputfile_()

        def block1():
            self._pattern(r'\s+')
            self._regions_()
        self._closure(block1)
        self._check_eof()

    @graken()
    def _samtools_00_(self):
        self._token('samtools')
        self._pattern(r'\s+')
        self._token('flagstat')
        self._pattern(r'\s+')
        self._inputfile_()
        self._check_eof()

    @graken()
    def _samtools_01_(self):
        self._token('samtools')
        self._pattern(r'\s+')
        self._token('index')
        self._pattern(r'\s+')
        self._inputfile_()
        self._check_eof()

    @graken()
    def _samtools_02_(self):
        self._token('samtools')
        self._pattern(r'\s+')
        self._token('merge')
        self._pattern(r'\s+')
        self._outputfile_()
        self._pattern(r'\s+')
        self._inputfile_()

        def block0():
            self._pattern(r'\s+')
            self._inputfile_()
        self._closure(block0)
        self._check_eof()

    @graken()
    def _samtools_03_(self):
        self._token('samtools')
        self._pattern(r'\s+')
        self._token('sort')

        def block0():
            self._pattern(r'\s+')
            self._sortoptions_()
        self._closure(block0)
        self._pattern(r'\s+')
        self._inputfile_()
        self._pattern(r'\s+')
        self._outprefix_()
        self._check_eof()

    @graken()
    def _sortoptions_(self):
        with self._group():
            with self._choice():
                with self._option():
                    self._sortoptions_flag_()
                with self._option():
                    self._token('-l')
                    self._pattern(r'\s+')
                    self._int_()
                    self.ast.setlist('compression_level', self.last_node)
                with self._option():
                    self._token('-@')
                    self._pattern(r'\s+')
                    self._int_()
                    self.ast.setlist('no_threads', self.last_node)
                with self._option():
                    self._token('-m')
                    self._pattern(r'\s+')
                    self._string_()
                    self.ast.setlist('thread_memory', self.last_node)
                self._error('no available options')

        self.ast._define(
            [],
            ['compression_level', 'no_threads', 'thread_memory']
        )

    @graken()
    def _sortoptions_flag_(self):
        self._token('-')

        def block0():
            with self._choice():
                with self._option():
                    self._token('n')
                    self.ast.setlist('sort_by_read', self.last_node)
                with self._option():
                    self._token('f')
                    self.ast.setlist('prefix_is_fullname', self.last_node)
                with self._option():
                    self._token('o')
                    self.ast.setlist('output_to_stdout', self.last_node)
                self._error('expecting one of: f n o')
        self._positive_closure(block0)

        self.ast._define(
            [],
            ['sort_by_read', 'prefix_is_fullname', 'output_to_stdout']
        )

    @graken()
    def _viewoptions_(self):
        with self._group():
            with self._choice():
                with self._option():
                    self._viewoptions_flag_()
                with self._option():
                    self._token('-@')
                    self._pattern(r'\s+')
                    self._int_()
                with self._option():
                    self._token('-L')
                    self._pattern(r'\s+')
                    self._bedoverlap_()
                with self._option():
                    self._token('-t')
                    self._pattern(r'\s+')
                    self._file_()
                with self._option():
                    self._token('-T')
                    self._pattern(r'\s+')
                    self._file_()
                with self._option():
                    self._token('-o')
                    self._pattern(r'\s+')
                    self._file_()
                with self._option():
                    self._token('-R')
                    self._pattern(r'\s+')
                    self._file_()
                with self._option():
                    self._token('-f')
                    self._pattern(r'\s+')
                    self._int_()
                with self._option():
                    self._token('-F')
                    self._pattern(r'\s+')
                    self._int_()
                with self._option():
                    self._token('-q')
                    self._pattern(r'\s+')
                    self._int_()
                with self._option():
                    self._token('-l')
                    self._pattern(r'\s+')
                    self._string_()
                with self._option():
                    self._token('-r')
                    self._pattern(r'\s+')
                    self._string_()
                with self._option():
                    self._token('-s')
                    self._pattern(r'\s+')
                    self._float_()
                    self.ast.setlist('frac_subsample', self.last_node)
                self._error('no available options')

        self.ast._define(
            [],
            ['frac_subsample']
        )

    @graken()
    def _viewoptions_flag_(self):
        self._token('-')

        def block0():
            with self._choice():
                with self._option():
                    self._token('b')
                    self.ast.setlist('output_is_bam', self.last_node)
                with self._option():
                    self._token('h')
                    self.ast.setlist('output_header', self.last_node)
                with self._option():
                    self._token('H')
                with self._option():
                    self._token('S')
                    self.ast.setlist('input_is_sam', self.last_node)
                with self._option():
                    self._token('u')
                with self._option():
                    self._token('1')
                with self._option():
                    self._token('x')
                with self._option():
                    self._token('X')
                with self._option():
                    self._token('c')
                with self._option():
                    self._token('B')
                with self._option():
                    self._token('?')
                self._error('expecting one of: 1 ? B H S X b c h u x')
        self._positive_closure(block0)

        self.ast._define(
            [],
            ['output_is_bam', 'output_header', 'input_is_sam']
        )

    @graken()
    def _outputfile_(self):
        self._pattern(r'\S+\.bam')
        self.ast.setlist('outputfile', self.last_node)

        self.ast._define(
            [],
            ['outputfile']
        )

    @graken()
    def _inputfile_(self):
        self._pattern(r'\S+\.[bs]am')
        self.ast.setlist('inputfile', self.last_node)

        self.ast._define(
            [],
            ['inputfile']
        )

    @graken()
    def _bedoverlap_(self):
        self._file_()
        self.ast.setlist('bedoverlap', self.last_node)

        self.ast._define(
            [],
            ['bedoverlap']
        )

    @graken()
    def _regions_(self):
        self._pattern(r'\S+')
        self.ast.setlist('regions', self.last_node)

        self.ast._define(
            [],
            ['regions']
        )

    @graken()
    def _outprefix_(self):
        self._pattern(r'\S+')
        self.ast.setlist('outprefix', self.last_node)

        self.ast._define(
            [],
            ['outprefix']
        )

    @graken()
    def _sort_dasho_(self):
        self._token('-o')
        self.ast.setlist('sort_dasho', self.last_node)

        self.ast._define(
            [],
            ['sort_dasho']
        )

    @graken()
    def _file_(self):
        self._pattern(r'\S+')

    @graken()
    def _path_(self):
        self._file_()

    @graken()
    def _int_(self):
        self._pattern(r'[0-9]+')

    @graken()
    def _integer_(self):
        self._int_()

    @graken()
    def _float_(self):
        self._pattern(r'[0-9\.]+')

    @graken()
    def _string_(self):
        with self._group():
            with self._choice():
                with self._option():
                    self._pattern(r'"[^"]*"')
                with self._option():
                    self._pattern(r"'[^']*'")
                with self._option():
                    self._pattern(r'\S+')
                self._error('expecting one of: "[^"]*" \'[^\']*\' \\S+')

    @graken()
    def _str_(self):
        self._string_()


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

    def samtools(self, ast):
        return ast

    def samtools_00(self, ast):
        return ast

    def samtools_01(self, ast):
        return ast

    def samtools_02(self, ast):
        return ast

    def samtools_03(self, ast):
        return ast

    def sortoptions(self, ast):
        return ast

    def sortoptions_flag(self, ast):
        return ast

    def viewoptions(self, ast):
        return ast

    def viewoptions_flag(self, ast):
        return ast

    def outputfile(self, ast):
        return ast

    def inputfile(self, ast):
        return ast

    def bedoverlap(self, ast):
        return ast

    def regions(self, ast):
        return ast

    def outprefix(self, ast):
        return ast

    def sort_dasho(self, ast):
        return ast

    def file(self, ast):
        return ast

    def path(self, ast):
        return ast

    def int(self, ast):
        return ast

    def integer(self, ast):
        return ast

    def float(self, ast):
        return ast

    def string(self, ast):
        return ast

    def str(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
    )

