#!/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 API representation.
"""

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 debug_mode, version
    from asterstudy.datamodel import History, UndoRedo, comm2study, study2comm, study2code
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 _check_text_diff(ref, cur):
    if ref != cur:
        from difflib import context_diff
        for line in context_diff(ref.split('\n'), cur.split('\n')):
            print line
        return False
    return True

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 API."
    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)

    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

    if options.debug:
        debug_mode.DEBUG = 1

    # Process input arguments.
    # TODO: use export function to convert file
    for arg in args:
        momento = UndoRedo(History())
        case = momento.model.current_case

        name = os.path.splitext(os.path.basename(arg))[0]
        stage = case.create_stage(name)
        momento.commit("create a stage")
        text = open(arg).read()

        comm2study(text, stage)
        momento.commit("populate this stage")

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

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

        stage2 = case.create_stage(name + '2')
        momento.commit("create another stage")

        text2 = study2code(stage, 'stage2')
        momento.commit("populate this stage")

        if options.debug:
            print text2

        exec(text2)  # pragma pylint: disable=exec-used

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

        text4 = study2comm(stage2)

        assert _check_text_diff(text1, text4)

    return 0

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

#------------------------------------------------------------------------------
