# This file is part of the Coral project.
# Please read the copyright notice in the LICENSE file.

# -*- coding: UTF-8 -*-
#
# diff - script to calculate the difference between two XMI files
#
# SYNOPSIS
#
# Explained in usage()
#
# DESCRIPTION
#
# diff calculates the difference between two XMI files
# as detailed in "Difference and Union of Models", in
# Proceedings of the UML 2003 conference.
#
# A DIFF10 model is given as output. DIFF10 is unfortunately
# not documented further.
#
# AUTHORS
#
# Marcus Alanen <maalanen@abo.fi> 2004
#

def ordinary_diff(file1, file2):
    import os
    os.execl("/usr/bin/diff", "diff", "-u", file1, file2)

def main(arguments):
    def usage():
        print "Usage: diff [ --help | --version | [ --type xmitype ] [--diagram=(no|only|both)]"
        print "            filename1 filename2 [outputfilename] ]"
        print ""
        print "Options:"
        print "  --help         Display this information."
        print "  --version      Display version information and exit."
        print "  --type         Sets the XMI type of the output file."
        print "                 Possible values are 1.2 or 2.0."
        print "  --diagram      How to handle diagrams."
        print "                 no   = no diagram information."
        print "                 only = only diagram information."
        print "                 both = both diagram and abstract information (default)."
        print ""
        print "Options -u and -L file are ignored for Subversion compatibility."
        print ""
        print "The given filenames are loaded and the difference is calculated."
        print "The resulting difference model is output on standard output,"
        print "or to the given filename outputfilename."
        print ""

    def version():
        import coral
        print "This is Coral version",coral.version, " (diff script)"
        
    import sys
    import getopt

    try:
        opts, args = getopt.getopt(arguments, "huL:", ["help", "version", "type=", "diagram="])
    except getopt.GetoptError:
        import traceback
        traceback.print_exc()
        usage()
        sys.exit(2)

    opt_xmitype = "2.0"
    opt_diagram = "both"
    
    # Determines if we output a suitable preamble a la Subversion
    is_called_by_subversion = False

    L = []
    
    for o,a in opts:
        if o in ("-h", "--help"):
            usage()
            sys.exit(0)
        elif o in ("--version"):
            version()
            sys.exit(0)
        elif o in ("--type"):
            opt_xmitype = a
        elif o in ("--diagram"):
            opt_diagram = a
        elif o in ("-L"):
            # Ignore for Subversion compatibility
            is_called_by_subversion = True
            L.append(a)
        elif o in ("-u"):
            # Ignore for Subversion compatibility
            pass
        else:
            usage()
            sys.exit(2)

    if len(args) < 2 or len(args) > 3:
        usage()
        sys.exit(2)

    import coral
    try:
        prj1 = coral.loadDocument(args[0])
    except RuntimeError:
        ordinary_diff(args[0], args[1])
        
    prj2 = coral.loadDocument(args[1])

    params = 0
    if opt_diagram == "no":
        params += coral.MODELDIFFERENCE_IGNORE_DIAGRAM_INFORMATION
    elif opt_diagram == "only":
        params += coral.MODELDIFFERENCE_ONLY_DIAGRAM_INFORMATION
    elif opt_diagram == "both":
        pass
    else:
        sys.stderr.write("Invalid diagram option. Must be no, only, or both.\n")
        sys.exit(2)
        
    md = coral.ModelDifference(prj1.contents(),
                               prj2.contents(),
                               params)

    p = coral.Project()
    p.setXMIFormat(opt_xmitype)
    md.__setProject__(p)

    if is_called_by_subversion and len(L) == 2:
        print "--- " + L[0]
        print "+++ " + L[1]

    if len(args) == 3:
        p.setFilename(args[2])
        coral.saveDocument(p)
    else:
        s = coral.saveDocument_str(p.contents(), p.getXMIFormat())
        sys.stdout.write(s)

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