#!/usr/bin/env python
import argparse
from xym import xym
from xym import __version__
import re

def run():
    parser = argparse.ArgumentParser(description='Extracts one or more YANG'
                                     'models from an IETF RFC or draft text file')
    parser.add_argument(
        "source",
        help="The URL or file name of the RFC/draft text from which to get the model")
    parser.add_argument(
        "--rfcxml", action='store_true', default=False,
        help="Parse a file in RFCXMLv3 format")
    parser.add_argument(
        "--srcdir", default='.',
        help="Optional: directory where to find the source text; default is './'")
    parser.add_argument(
        "--dstdir", default='.',
        help="Optional: directory where to put the extracted YANG module(s); default is './'")
    parser.add_argument(
        "--strict", type=bool, default=False,
        help='Optional flag that determines syntax enforcement; '
        "'If set to 'True', the <CODE BEGINS> / <CODE ENDS> "
        "tags are required; default is 'False'")
    parser.add_argument(
        "--strict-name", action='store_true', default=False,
        help="Optional flag that determines name enforcement; "
             "If set to 'True', name will be resolved from module "
             "itself and not from name given in the document;"
             " default is 'False'")
    parser.add_argument(
        "--strict-examples", action='store_true', default=False,
        help="Only output valid examples when in strict mode")
    parser.add_argument(
        "--write-dict", action='store_true',
        default=False, help="Optional: write email and module mapping")
    parser.add_argument(
        "--debug", type=int, default=0,
        help="Optional: debug level - determines the amount of debug "
        "info printed to console; default is 0 (no debug info printed)")
    parser.add_argument(
        "--force-revision-pyang", action='store_true', default=False,
        help="Optional: if True it will check if file contains correct revision in file name."
        "If it doesnt it will automatically add the correct revision to the filename using pyang")
    parser.add_argument(
        "--force-revision-regexp", action='store_true', default=False,
        help="Optional: if True it will check if file contains correct revision in file name."
        "If it doesnt it will automatically add the correct revision to the filename using regular"
        " expression")
    parser.add_argument(
        "--version", action='version',
        version='%(prog)s {version}'.format(version=__version__))
    group = parser.add_mutually_exclusive_group()
    group.add_argument(
        "--parse-only-modules", nargs='+',
        help="Optional: it will parse only modules added in the list in arguments."
    )
    group.add_argument(
        "--skip-modules", nargs='+',
        help="Optional: it will skip modules added in the list in arguments."
    )

    args = parser.parse_args()

    extracted_models = xym.xym(args.source,
                               args.srcdir,
                               args.dstdir,
                               args.strict,
                               args.strict_name,
                               args.strict_examples,
                               args.debug,
                               force_revision_pyang=args.force_revision_pyang,
                               force_revision_regexp=args.force_revision_regexp,
                               skip_modules=args.skip_modules,
                               parse_only_modules=args.parse_only_modules,
                               rfcxml=args.rfcxml)
    if len(extracted_models) > 0:
        if args.strict:
            print("Created the following models that conform to the strict guidelines:")
        else:
            print("Created the following models:")
        for em in extracted_models:
            print('%s' % em)
        if args.write_dict:
            url = re.compile(
                r'^(?:http|ftp)s?://'  # http:// or https://
                r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?)|'  # domain
                r'localhost|'  # localhost...
                r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})'  # ...or ip
                r'(?::\d+)?'  # optional port
                r'(?:/?|[/?]\S+)$', re.IGNORECASE)
            fqfn = args.dstdir + '/yang.dict'
            is_url = url.match(args.source)
            draft_file = ""
            if is_url:
                draft_file = args.source.rsplit('/', 1)[1]
            else:
                draft_file = args.source
            draft_name = draft_file.split('.', 1)[0]
            if draft_name.startswith("draft"):
                                draft_email = draft_name.rsplit('-', 1)[0] + "@ietf.org"
            else:
                                draft_email = draft_name + "@ietf.org"
            with open(fqfn, "a") as of:
                for em in extracted_models:
                    of.write('%s : %s\n' % (em.split('@', 1)[0], draft_email))
                of.close()
    else:
        print('No models created.')


if __name__ == '__main__':
    run()
