#!/usr/bin/python2.5
#
# This script is the command-line interface to FFC. It parses
# command-line arguments and wraps the given form file code in a
# Python module which is then executed.

__author__ = "Anders Logg (logg@simula.no)"
__date__ = "2004-10-14 -- 2009-08-25"
__copyright__ = "Copyright (C) 2004-2009 Anders Logg"
__license__  = "GNU GPL version 3 or any later version"

# Modified by Johan Jansson, 2005.
# Modified by Ola Skavhaug, 2006.
# Modified by Dag Lindbo, 2008.
# Modified by Kristian B. Oelgaard 2009.

# Python modules
import sys
import getopt
import os.path

# UFL modules
from ufl.log import UFLException
from ufl.algorithms import load_ufl_file

# FFC modules
from ffc.common.log import info, set_level, DEBUG, ERROR
from ffc.common.constants import FFC_OPTIONS, FFC_VERSION
from ffc.compiler.compiler import compile

def error(msg):
    "Print error message (cannot use log system at top level)."
    print "\n".join(["*** FFC: " + line for line in msg.split("\n")])

def info_version():
    "Print version number."
    info("""\
This is FFC, the FEniCS Form Compiler, version %s.
For further information, visit http://www.fenics.org/ffc/.
""" % FFC_VERSION)

def info_usage():
    "Print usage information."
    info_version()
    info("""Usage: ffc [OPTION]... input.form

For information about the FFC command-line interface, refer to
the FFC man page which may invoked by 'man ffc' (if installed).
""")

def main(argv):
    "Main function."

    # Get options and set log level (such that info_usage() will work)
    options = FFC_OPTIONS.copy()
    set_level(options["log_level"])

    # Get command-line arguments
    try:
        opts, args = getopt.getopt(argv, \
        "hvdsl:r:f:Oo:q:", \
        ["help", "version", "debug", "silent", "language=", "representation=",
         "optimize", "output-directory=", "quadrature-rule="])
    except getopt.GetoptError:
        info_usage()
        error("Illegal command-line arguments.")
        return 1

    # Check for --help
    if ("-h", "") in opts or ("--help", "") in opts:
        info_usage()
        return 0

    # Check for --version
    if ("-v", "") in opts or ("--version", "") in opts:
        info_version()
        return 0

    # Check that we get at least one file
    if len(args) == 0:
        error("Missing file.")
        return 1

    # Parse command-line options
    for opt, arg in opts:
        if opt in ("-d", "--debug"):
             options["log_level"] = DEBUG
        elif opt in ("-s", "--silent"):
            options["log_level"] = ERROR
        elif opt in ("-l", "--language"):
            options["format"] = arg
        elif opt in ("-r", "--representation"):
            options["representation"] = arg
        elif opt in ("-q", "--quadrature-rule"):
            options["quadrature_rule"] = arg
        elif opt == "-f":
            if len(arg.split("=")) == 2:
                (key, value) = arg.split("=")
                options[key] = value
            elif len(arg.split("==")) == 1:
                key = arg.split("=")[0]
                options[arg] = True
            else:
                info_usage()
                return 1
        elif opt in ("-O", "--optimize"):
            options["optimize"] = True
        elif opt in ("-o", "--output-directory"):
            options["output_dir"] = arg

    # Set log_level again in case -d or -s was used on the command line
    set_level(options["log_level"])

    # Print a nice message
    info_version()

    # Call parser and compiler for each file
    for filename in args:

        # Get filename suffix
        suffix = filename.split(".")[-1]

        # Check file suffix and load ufl file
        if suffix == "ufl":
            ufd = load_ufl_file(filename)
        elif suffix == "form":
            error("Old style .form files are no longer supported. Use form2ufl to convert to UFL format.")
            return 1
        else:
            error("Expecting a UFL form file (.ufl).")
            return 1

        # Catch exceptions only when not in debug mode
        if options["log_level"] <= DEBUG:
            compile(ufd.forms + ufd.elements, filename.split(".")[0], options)
        else:
            try:
                compile(ufd.forms + ufd.elements, filename.split(".")[0], options)
            except UFLException, exception:
                info("")
                error(str(exception))
                error("To get more information about this error, rerun FFC with --debug.")
                return 1

    return 0

if __name__ == "__main__":
    sys.exit(main(sys.argv[1:]))
