#!/usr/bin/env python
# -*- coding: utf-8 -*-

# Copyright 2016 EDF R&D
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, you may download a copy of license
# from https://www.gnu.org/licenses/gpl-3.0.

"""Convert Code_Aster COMM file(s) into AsterStudy document."""

from __future__ import unicode_literals

import os
import sys
import optparse
import traceback

LIBDIR = ''

# Add libdir to sys.path.
if LIBDIR != '@' 'LIBDIR' '@':
    # ... for install tree.
    if not os.path.isabs(LIBDIR):
        LIBDIR = os.path.join(os.path.dirname(os.path.realpath(__file__)),
                              LIBDIR)
        LIBDIR = os.path.abspath(LIBDIR)
    sys.path.insert(0, LIBDIR)
else:
    # ... for source tree.
    sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)))

try:
    # pragma pylint: disable=wrong-import-position,relative-import
    from asterstudy.common import ConversionError, debug_mode, version
    from asterstudy.datamodel import (CATA, History, comm2study,
                           study2comm)
    from asterstudy.datamodel.general import ConversionLevel
except ImportError as err:
    sys.stderr.write("abort: couldn't find astergui libraries in [%s]\n" %
                     ' '.join(sys.path))
    sys.stderr.write("(check your install and PYTHONPATH)\n")
    if os.getenv("DEBUG", 0):
        sys.stderr.write("ERROR: %s\n" % err)
        traceback.print_exc()
    sys.exit(-1)

def main():
    """Main function."""

    # Parse command line.
    program = os.path.basename(sys.argv[0])
    usage = "%prog [options] [COMM_FILE ...]"
    description = "Convert Code_Aster COMM file into AsterStudy document."
    formatter = optparse.IndentedHelpFormatter(max_help_position=30)

    parser = optparse.OptionParser(usage=usage, description=description,
                                   formatter=formatter)

    phelp = ("show program's version number and exit")
    parser.add_option("-v", "--version", action="store_true", dest="version",
                      help=phelp)
    phelp = ("turn debug mode on; default: OFF")
    parser.add_option("-g", "--debug", dest="debug", action="store_true",
                      default=False, help=phelp)
    phelp = ("check re-import from study file to COMM file; for test purpose"
             " only; default: OFF")
    parser.add_option("-e", "--export", dest="export", action="store_true",
                      default=False, help=phelp)
    phelp = ("use the strict import mode; default: OFF")
    parser.add_option("-s", "--strict", dest="strict", action="store_true",
                      default=False, help=phelp)
    parser.add_option("-l", "--limit", dest="limit", action="store", type=int,
                      default=0, help="passed to study2comm: default: 0")

    options, args = parser.parse_args()

    if options.version:
        sys.stdout.write("{} {}\n".format(program, version()))
        sys.exit(0)

    # Check command line options and arguments.
    if not args:
        sys.stderr.write("abort: no input COMM files specified\n\n")
        parser.print_usage(file=sys.stderr)
        return -1

    for arg in args:
        if not os.path.exists(arg):
            sys.stderr.write("abort: '%s' does not exist\n" % arg)
            return -1
        if not os.path.isfile(arg):
            sys.stderr.write("'%s' is not a file\n" % arg)
            return -1

    history = History()
    case = history.current_case

    if options.debug:
        debug_mode.DEBUG = 1
        check_func = CATA.package('SyntaxChecker').checkCommandSyntax
        check_func.func_defaults = (True,)

    # Process input arguments.
    strict_mode = ConversionLevel.NoFail
    if options.strict:
        strict_mode = ConversionLevel.Syntaxic
    for arg in args:
        name = os.path.splitext(os.path.basename(arg))[0]
        stage = case.create_stage(name)
        text = open(arg).read()
        try:
            comm2study(text, stage, strict=strict_mode)
        except ConversionError, exc:
            print "Original traceback:\n", exc.details
            raise

        for command in stage:
            command.check(safe=False)

        if not options.export:
            continue

        text1 = study2comm(stage, limit=options.limit)
        if options.debug:
            print text1

        if options.limit:
            # if the output is truncated, the text will be invalid
            continue

        stage = case.create_stage(name + '-debug')
        try:
            comm2study(text1, stage, strict=strict_mode)
        except ConversionError, exc:
            print "Original traceback:\n", exc.details
            raise

        for command in stage:
            command.check(safe=False)

        text2 = study2comm(stage, limit=options.limit)
        if options.debug:
            print text2

        assert text1 == text2

    return 0

if __name__ == "__main__":
    sys.exit(main())
