\
import sys
import os
import _paths


def handle_options():
    """Returns options values as map."""

    import argparse
    parser = argparse.ArgumentParser(description="Converts a TFPG (associations) XML file into textual format or viceversa")

    parser.add_argument("--tfpg-file", "-t",
                        dest="tfpg",
                        action="store",
                        default=None,
                        help="The TFPG file (can be in XML or human readable format)")

    parser.add_argument("--associations-file", "-a",
                        dest="assoc",
                        action="store",
                        default=None,
                        help="TFPG SMV associations file")

    args = parser.parse_args()

    if args.tfpg is not None and not os.path.exists(args.tfpg):
        parser.error("The specified TFPG file is not valid: %s." %args.tfpg)
        pass

    if args.assoc is not None and not os.path.exists(args.assoc):
        parser.error("The specified associations file is not valid: %s." %args.assoc)
        pass

    if args.tfpg is None and args.assoc is None:
        parser.error("At least a TFPG file or an associations file must be specified")

    return args


if __name__ == "__main__":

    _paths.setup_path()

    # setup logging
    import xsap.utils.misc.log
    xsap.utils.misc.log.init()
    args = handle_options()

    tfpg_fname = args.tfpg       # The name of the tfpg model (XML format)
    assoc_fname = args.assoc     # The name of the tfpg SMV associations file

    if tfpg_fname is not None:
        tfpg_file_ext = os.path.splitext(tfpg_fname)[1]
        tfpg = None
        errors = []

        if tfpg_file_ext in [".txml", ".xml"]:
            from xsap.data_structure.tfpg.xml.tfpg import parse_tfpg_xml_file_to_internal_struct
            tfpg, errors = parse_tfpg_xml_file_to_internal_struct(tfpg_fname)
        elif tfpg_file_ext == ".tfpg":
            from xsap.data_structure.tfpg.txt.tfpg import parse_tfpg_txt_file_to_internal_struct
            tfpg = parse_tfpg_txt_file_to_internal_struct(tfpg_fname)
        else:
            print "Error! Unknown format for the TFPG file: %s." %tfpg_file_ext
            sys.exit(1)

        from xsap.data_structure.tfpg.tfpg_errors import UnreachableDiscrepancy
        if len(tfpg.get_errors_list()) > 0:
            for err in tfpg.get_errors_list():
                if isinstance(err, UnreachableDiscrepancy):
                    print "Warning! " + str(err)
        if len(errors) > 0:
            for err in errors:
                raise err

        if tfpg_file_ext in [".txml", ".xml"]:
            from xsap.data_structure.tfpg.txt.tfpg import dump_tfpg_to_txt_file
            tfpg_out_fname = os.path.splitext(tfpg_fname)[0] + ".tfpg"
            dump_tfpg_to_txt_file(tfpg, tfpg_out_fname)
        elif tfpg_file_ext in ".tfpg":
            tfpg_out_fname = os.path.splitext(tfpg_fname)[0] + ".txml"
            tfpg.dump_to_xml(tfpg_out_fname)

        print "TFPG dumped to file: %s" %tfpg_out_fname


    if assoc_fname is not None:
        assoc_file_ext = os.path.splitext(assoc_fname)[1]
        associations = None

        if assoc_file_ext in [".axml", ".xml"]:
            from xsap.data_structure.tfpg.xml.tfpg_associations import parse_assoc_xml_file_to_internal_struct
            from xsap.data_structure.tfpg.txt.tfpg_associations import dump_associations_to_txt_file

            associations = parse_assoc_xml_file_to_internal_struct(assoc_fname)

            if (len(associations.get_var_names_of_unmonitored_discr()) == 0 and len(associations.get_var_names_of_monitored_discr()) == 0) or \
                    len(associations.get_var_names_of_failure_modes()) == 0 or \
                    len(associations.get_var_names_of_tfpg_modes()) == 0:
                print "Error! Associations file must contain at least a failure mode, a discrepancy and a system mode"
                sys.exit(1)

            assoc_out_fname = os.path.splitext(assoc_fname)[0] + ".tfpga"
            dump_associations_to_txt_file(associations, assoc_out_fname)

        elif assoc_file_ext == ".tfpga":
            from xsap.data_structure.tfpg.txt.tfpg_associations import parse_assoc_txt_file_to_internal_struct
            from xsap.data_structure.tfpg.xml.tfpg_associations import create_associations_document_from_list

            associations = parse_assoc_txt_file_to_internal_struct(assoc_fname)

            if (len(associations.get_var_names_of_unmonitored_discr()) == 0 and len(associations.get_var_names_of_monitored_discr()) == 0) or \
                    len(associations.get_var_names_of_failure_modes()) == 0 or \
                    len(associations.get_var_names_of_tfpg_modes()) == 0:
                print "Error! Associations file must contain at least a failure mode, a discrepancy and a system mode"
                sys.exit(1)

            assoc_out_fname = os.path.splitext(assoc_fname)[0] + ".axml"
            assoc_file = open(assoc_out_fname, "w")
            assoc_file.write(str(create_associations_document_from_list(associations)))
            assoc_file.close()

        else:
            print "Error! Unknown format for the TFPG associations file: %s." %assoc_file_ext
            sys.exit(1)

        print "Associations dumped to file: %s" %assoc_out_fname

        pass
