# Path: vcfpy/parser.py
# REQUIRE_SAMPLE_HEADER = ("#CHROM", "POS", "ID", "REF", "ALT", "QUAL", "FILTER", "INFO", "FORMAT")
# REQUIRE_NO_SAMPLE_HEADER = ("#CHROM", "POS", "ID", "REF", "ALT", "QUAL", "FILTER", "INFO")
# SUPPORTED_VCF_VERSIONS = ("VCFv4.0", "VCFv4.1", "VCFv4.2", "VCFv4.3")
#     NORMAL = 0
#     QUOTED = 1
#     ESCAPED = 2
#     ARRAY = 3
#     DELIM = 4
#         DISPATCH = {
#             self.NORMAL: self._handle_normal,
#             self.QUOTED: self._handle_quoted,
#             self.ARRAY: self._handle_array,
#             self.DELIM: self._handle_delim,
#             self.ESCAPED: self._handle_escaped,
#         }
# _CONVERTERS = {
#     "Integer": int,
#     "Float": float,
#     "Flag": lambda x: True,
#     "Character": str,
#     "String": str,
# }
# BREAKEND_PATTERN = re.compile("[\\[\\]]")
#     FWD_REV = {True: record.FORWARD, False: record.REVERSE}
#         TABLE = {
#             ".": len(value),
#             "A": num_alts,
#             "R": num_alts + 1,
#             "G": binomial(num_alts + 1, 2),  # diploid only at the moment
#         }
#         TABLE = {
#             ".": len(value),
#             "A": num_alts,
#             "R": num_alts + 1,
#             "G": binomial(num_alts + num_alleles, num_alleles),
#         }
# class QuotedStringSplitter:
# class HeaderLineParserBase:
# class StupidHeaderLineParser(HeaderLineParserBase):
# class MappingHeaderLineParser(HeaderLineParserBase):
# class HeaderParser:
# class RecordParser:
# class HeaderChecker:
# class NoopInfoChecker:
# class InfoChecker:
# class NoopFormatChecker:
# class FormatChecker:
# class Parser:
#     def __init__(self, delim=",", quote='"', brackets="[]"):
#     def run(self, s):
#     def _handle_normal(self, c, pos, begins, ends):  # pylint: disable=W0613
#     def _handle_quoted(self, c, pos, begins, ends):  # pylint: disable=W0613
#     def _handle_array(self, c, pos, begins, ends):  # pylint: disable=W0613
#     def _handle_delim(self, c, pos, begins, ends):  # pylint: disable=W0613
#     def _handle_escaped(self, c, pos, begins, ends):  # pylint: disable=W0613
# def split_quoted_string(s, delim=",", quote='"', brackets="[]"):
# def split_mapping(pair_str):
# def parse_mapping(value):
#     def parse_key_value(self, key, value):
#     def parse_key_value(self, key, value):
#     def __init__(self, line_class):
#     def parse_key_value(self, key, value):
# def build_header_parsers():
# def convert_field_value(type_, value):
# def parse_field_value(field_info, value):
# def parse_breakend(alt_str):
# def process_sub_grow(ref, alt_str):
# def process_sub_shrink(ref, alt_str):
# def process_sub(ref, alt_str):
# def process_alt(header, ref, alt_str):  # pylint: disable=W0613
#     def __init__(self):
#     def parse_line(self, line):
#     def __init__(self, header, samples, record_checks=None):
#     def parse_line(self, line_str):
#     def _handle_calls(self, alts, format_, format_str, arr):
#     def _check_filters(self, filt, source, sample=None):
#     def _check_filter(self, f, source, sample):
#     def _split_line(self, line_str):
#     def _parse_info(self, info_str, num_alts):
#     def _parse_calls_data(klass, format_, infos, gt_str):
#     def run(self, header):
#     def _check_header_lines(self, header_lines):
# def binomial(n, k):
#     def __init__(self):
#     def run(self, key, value, num_alts):
#     def __init__(self, header):
#     def run(self, key, value, num_alts):
#     def __init__(self):
#     def run(self, call, num_alts):
#     def __init__(self, header):
#     def run(self, call, num_alts):
#     def _check_count(self, call, key, value, num_alts):
#     def __init__(self, stream, path=None, record_checks=None):
#     def _read_next_line(self):
#     def parse_header(self, parsed_samples=None):
#     def _handle_sample_line(self, parsed_samples=None):
#     def _check_samples_line(klass, arr):
#     def parse_line(self, line):
#     def parse_next_record(self):
#     def print_warn_summary(self):


import argparse
import io
import sys
import statistics
import time
from vcfpy import parser

LINE = """
20\t14370\trs6054257\tG\tA\t29\tPASS\tNS=3;DP=14;AF=0.5;DB;H2\tGT:GQ:DP:HQ\t0|0:48:1:51,51\t1|0:48:8:51,51\t1/1:43:5:.,.
""".lstrip()


def run(args):
    # Setup parser
    p = parser.VCFParser(io.StringIO(HEADER), "<builtin>")
    # Parse header
    p.parse_header()
    # Parse line several times
    times = []
    for r in range(args.repetitions):
        begin = time.clock()
        for _ in range(args.line_count):
            r = p._record_parser.parse_line(LINE)  # noqa
            if args.debug:
                print(r, file=sys.stderr)
        times.append(time.clock() - begin)
    print(
        "Took {:.3} seconds (stdev {:.3})".format(statistics.mean(times), statistics.stdev(times)),
        file=sys.stderr,
    )


def main(argv=None):
    """Main program entry point for parsing command line arguments"""
    parser = argparse.ArgumentParser(description="Parser benchmark")


# Path: vcfpy/parser.py
# REQUIRE_SAMPLE_HEADER = ("#CHROM", "POS", "ID", "REF", "ALT", "QUAL", "FILTER", "INFO", "FORMAT")
# REQUIRE_NO_SAMPLE_HEADER = ("#CHROM", "POS", "ID", "REF", "ALT", "QUAL", "FILTER", "INFO")
# SUPPORTED_VCF_VERSIONS = ("VCFv4.0", "VCFv4.1", "VCFv4.2", "VCFv4.3")
#     NORMAL = 0
#     QUOTED = 1
#     ESCAPED = 2
#     ARRAY = 3
#     DELIM = 4
#         DISPATCH = {
#             self.NORMAL: self._handle_normal,
#             self.QUOTED: self._handle_quoted,
#             self.ARRAY: self._handle_array,
#             self.DELIM: self._handle_delim,
#             self.ESCAPED: self._handle_escaped,
#         }
# _CONVERTERS = {
#     "Integer": int,
#     "Float": float,
#     "Flag": lambda x: True,
#     "Character": str,
#     "String": str,
# }
# BREAKEND_PATTERN = re.compile("[\\[\\]]")
#     FWD_REV = {True: record.FORWARD, False: record.REVERSE}
#         TABLE = {
#             ".": len(value),
#             "A": num_alts,
#             "R": num_alts + 1,
#             "G": binomial(num_alts + 1, 2),  # diploid only at the moment
#         }
#         TABLE = {
#             ".": len(value),
#             "A": num_alts,
#             "R": num_alts + 1,
#             "G": binomial(num_alts + num_alleles, num_alleles),
#         }
# class QuotedStringSplitter:
# class HeaderLineParserBase:
# class StupidHeaderLineParser(HeaderLineParserBase):
# class MappingHeaderLineParser(HeaderLineParserBase):
# class HeaderParser:
# class RecordParser:
# class HeaderChecker:
# class NoopInfoChecker:
# class InfoChecker:
# class NoopFormatChecker:
# class FormatChecker:
# class Parser:
#     def __init__(self, delim=",", quote='"', brackets="[]"):
#     def run(self, s):
#     def _handle_normal(self, c, pos, begins, ends):  # pylint: disable=W0613
#     def _handle_quoted(self, c, pos, begins, ends):  # pylint: disable=W0613
#     def _handle_array(self, c, pos, begins, ends):  # pylint: disable=W0613
#     def _handle_delim(self, c, pos, begins, ends):  # pylint: disable=W0613
#     def _handle_escaped(self, c, pos, begins, ends):  # pylint: disable=W0613
# def split_quoted_string(s, delim=",", quote='"', brackets="[]"):
# def split_mapping(pair_str):
# def parse_mapping(value):
#     def parse_key_value(self, key, value):
#     def parse_key_value(self, key, value):
#     def __init__(self, line_class):
#     def parse_key_value(self, key, value):
# def build_header_parsers():
# def convert_field_value(type_, value):
# def parse_field_value(field_info, value):
# def parse_breakend(alt_str):
# def process_sub_grow(ref, alt_str):
# def process_sub_shrink(ref, alt_str):
# def process_sub(ref, alt_str):
# def process_alt(header, ref, alt_str):  # pylint: disable=W0613
#     def __init__(self):
#     def parse_line(self, line):
#     def __init__(self, header, samples, record_checks=None):
#     def parse_line(self, line_str):
#     def _handle_calls(self, alts, format_, format_str, arr):
#     def _check_filters(self, filt, source, sample=None):
#     def _check_filter(self, f, source, sample):
#     def _split_line(self, line_str):
#     def _parse_info(self, info_str, num_alts):
#     def _parse_calls_data(klass, format_, infos, gt_str):
#     def run(self, header):
#     def _check_header_lines(self, header_lines):
# def binomial(n, k):
#     def __init__(self):
#     def run(self, key, value, num_alts):
#     def __init__(self, header):
#     def run(self, key, value, num_alts):
#     def __init__(self):
#     def run(self, call, num_alts):
#     def __init__(self, header):
#     def run(self, call, num_alts):
#     def _check_count(self, call, key, value, num_alts):
#     def __init__(self, stream, path=None, record_checks=None):
#     def _read_next_line(self):
#     def parse_header(self, parsed_samples=None):
#     def _handle_sample_line(self, parsed_samples=None):
#     def _check_samples_line(klass, arr):
#     def parse_line(self, line):
#     def parse_next_record(self):
#     def print_warn_summary(self):


# Path: examples/bench_parse.py
import argparse
import io
import sys
import statistics
import time
from vcfpy import parser


LINE = """
20\t14370\trs6054257\tG\tA\t29\tPASS\tNS=3;DP=14;AF=0.5;DB;H2\tGT:GQ:DP:HQ\t0|0:48:1:51,51\t1|0:48:8:51,51\t1/1:43:5:.,.
""".lstrip()


def run(args):
    # Setup parser
    p = parser.VCFParser(io.StringIO(HEADER), "<builtin>")
    # Parse header
    p.parse_header()
    # Parse line several times
    times = []
    for r in range(args.repetitions):
        begin = time.clock()
        for _ in range(args.line_count):
            r = p._record_parser.parse_line(LINE)  # noqa
            if args.debug:
                print(r, file=sys.stderr)
        times.append(time.clock() - begin)
    print(
        "Took {:.3} seconds (stdev {:.3})".format(statistics.mean(times), statistics.stdev(times)),
        file=sys.stderr,
    )


def main(argv=None):
    """Main program entry point for parsing command line arguments"""
    parser = argparse.ArgumentParser(description="Parser benchmark")


    parser.add_argument("--debug", default=False, action="store_true", help="Enable debugging")