package jdiff;

import java.util.*;

/**
 * Convert some remove and add operations into change operations.
 *
 * Once the numbers of members removed and added are known
 * we can deduce more information about changes. For instance, if there are
 * two methods with the same name, and one or more of them has a 
 * parameter type change, then this can only be reported as removing 
 * the old version(s) and adding the new version(s), because there are 
 * multiple methods with the same name. 
 *
 * However, if only <i>one</i> method with a given name is removed, and  
 * only <i>one</i> method with the same name is added, we can convert these
 * operations to a change operation. For constructors, this is true if 
 * the types are the same. For fields, the field names have to be the same, 
 * though this should never occur, since field names are unique.
 *
 * Another merge which can be made is if two or more methods with the same name
 * were marked as removed and added because of changes other than signature.
 *
 * See the file LICENSE.txt for copyright details.
 * @author Matthew Doar, mdoar@pobox.com
 */
class MergeChanges {

    /**
     * Convert some remove and add operations into change operations.
     *
     * Note that if a single thread modifies a collection directly while it is 
     * iterating over the collection with a fail-fast iterator, the iterator 
     * will throw java.util.ConcurrentModificationException   
     */
    public static void mergeRemoveAdd(APIDiff apiDiff) {
        // Go through all the ClassDiff objects searching for the above cases.
        Iterator iter = apiDiff.packagesChanged.iterator();
        while (iter.hasNext()) {
            PackageDiff pkgDiff = (PackageDiff)(iter.next());
            Iterator iter2 = pkgDiff.classesChanged.iterator();
            while (iter2.hasNext()) {
                ClassDiff classDiff = (ClassDiff)(iter2.next());
                // Note: using iterators to step through the members gives a
                // ConcurrentModificationException exception with large files.
                // Constructors
                ConstructorAPI[] ctorArr = new ConstructorAPI[classDiff.ctorsRemoved.size()];
                ctorArr = (ConstructorAPI[])classDiff.ctorsRemoved.toArray(ctorArr);
                for (int ctorIdx = 0; ctorIdx < ctorArr.length; ctorIdx++) {
                    ConstructorAPI removedCtor = ctorArr[ctorIdx];
                    mergeRemoveAddCtor(removedCtor, classDiff, pkgDiff);
                }
                // Methods
                MethodAPI[] methodArr = new MethodAPI[classDiff.methodsRemoved.size()];
                methodArr = (MethodAPI[])classDiff.methodsRemoved.toArray(methodArr);
                for (int methodIdx = 0; methodIdx < methodArr.length; methodIdx++) {
                    MethodAPI removedMethod = methodArr[methodIdx];
                    // Only merge locally defined methods
                    if (removedMethod.inheritedFrom_ == null)
                        mergeRemoveAddMethod(removedMethod, classDiff, pkgDiff);
                }
                // Fields
                FieldAPI[] fieldArr = new FieldAPI[classDiff.fieldsRemoved.size()];
                fieldArr = (FieldAPI[])classDiff.fieldsRemoved.toArray(fieldArr);
                for (int fieldIdx = 0; fieldIdx < fieldArr.length; fieldIdx++) {
                    FieldAPI removedField = fieldArr[fieldIdx]; 
                    // Only merge locally defined fields
                    if (removedField.inheritedFrom_ == null)
                        mergeRemoveAddField(removedField, classDiff, pkgDiff);
                }
            }
        }        
    }

    /**
     * Convert some removed and added constructors into changed constructors.
     */
    public static void mergeRemoveAddCtor(ConstructorAPI removedCtor, ClassDiff classDiff, PackageDiff pkgDiff) {
        // Search on the type of the constructor
        int startRemoved = classDiff.ctorsRemoved.indexOf(removedCtor);
        int endRemoved = classDiff.ctorsRemoved.lastIndexOf(removedCtor);
        int startAdded = classDiff.ctorsAdded.indexOf(removedCtor);
        int endAdded = classDiff.ctorsAdded.lastIndexOf(removedCtor);
        if (startRemoved != -1 && startRemoved == endRemoved && 
            startAdded != -1 && startAdded == endAdded) {
            // There is only one constructor with the type of the
            // removedCtor in both the removed and added constructors.
            ConstructorAPI addedCtor = (ConstructorAPI)(classDiff.ctorsAdded.get(startAdded));
            // Create a MemberDiff for this change
            MemberDiff ctorDiff = new MemberDiff(classDiff.name_);
            ctorDiff.oldType_ = removedCtor.getSignature();
            ctorDiff.newType_ = addedCtor.getSignature(); // Should be the same as removedCtor.type
            ctorDiff.oldExceptions_ = removedCtor.exceptions_;
            ctorDiff.newExceptions_ = addedCtor.exceptions_;
            ctorDiff.addModifiersChange(removedCtor.modifiers_.diff(addedCtor.modifiers_));
            // Track changes in documentation
            if (APIComparator.docChanged(removedCtor.doc_, addedCtor.doc_)) {
                String type = ctorDiff.newType_;
                if (type.compareTo("void") == 0)
                    type = "";
                String fqName = pkgDiff.name_ + "." + classDiff.name_;
                String link1 = "<a href=\"" + fqName + HTMLReportGenerator.reportFileExt + "\" class=\"hiddenlink\">";
                String link2 = "<a href=\"" + fqName + HTMLReportGenerator.reportFileExt + "#" + fqName + ".ctor_changed(" + type + ")\" class=\"hiddenlink\">";
                String id = pkgDiff.name_ + "." + classDiff.name_ + ".ctor(" + HTMLReportGenerator.simpleName(type) + ")";
                String title = link1 + "Class <b>" + classDiff.name_ + 
                    "</b></a>, " + link2 + "constructor <b>" + classDiff.name_ + "(" + HTMLReportGenerator.simpleName(type) + ")</b></a>";
                ctorDiff.documentationChange_ = Diff.saveDocDiffs(pkgDiff.name_, classDiff.name_, removedCtor.doc_, addedCtor.doc_, id, title);
            }
            classDiff.ctorsChanged.add(ctorDiff);
            // Now remove the entries from the remove and add lists
            classDiff.ctorsRemoved.remove(startRemoved);
            classDiff.ctorsAdded.remove(startAdded);
            if (trace && ctorDiff.modifiersChange_ != null)
                System.out.println("Merged the removal and addition of constructor into one change: " + ctorDiff.modifiersChange_);
        }
    }

    /**
     * Convert some removed and added methods into changed methods.
     */
    public static void mergeRemoveAddMethod(MethodAPI removedMethod, 
                                            ClassDiff classDiff, 
                                            PackageDiff pkgDiff) {
        mergeSingleMethods(removedMethod, classDiff, pkgDiff);
        mergeMultipleMethods(removedMethod, classDiff, pkgDiff);
    }

    /**
     * Convert single removed and added methods into a changed method.
     */
    public static void mergeSingleMethods(MethodAPI removedMethod, ClassDiff classDiff, PackageDiff pkgDiff) {
        // Search on the name of the method
        int startRemoved = classDiff.methodsRemoved.indexOf(removedMethod);
        int endRemoved = classDiff.methodsRemoved.lastIndexOf(removedMethod);
        int startAdded = classDiff.methodsAdded.indexOf(removedMethod);
        int endAdded = classDiff.methodsAdded.lastIndexOf(removedMethod);
        if (startRemoved != -1 && startRemoved == endRemoved && 
            startAdded != -1 && startAdded == endAdded) {
            // There is only one method with the name of the
            // removedMethod in both the removed and added methods.
            MethodAPI addedMethod = (MethodAPI)(classDiff.methodsAdded.get(startAdded));
            if (addedMethod.inheritedFrom_ == null) {
                // Create a MemberDiff for this change
                MemberDiff methodDiff = new MemberDiff(removedMethod.name_);
                methodDiff.oldType_ = removedMethod.returnType_;
                methodDiff.newType_ = addedMethod.returnType_;
                methodDiff.oldSignature_ = removedMethod.getSignature();
                methodDiff.newSignature_ = addedMethod.getSignature();
                methodDiff.oldExceptions_ = removedMethod.exceptions_;
                methodDiff.newExceptions_ = addedMethod.exceptions_;
                // The addModifiersChange field may not have been
                // initialized yet if there were multiple methods of the same
                // name.
                diffMethods(methodDiff, removedMethod, addedMethod);
                methodDiff.addModifiersChange(removedMethod.modifiers_.diff(addedMethod.modifiers_));
                // Track changes in documentation
                if (APIComparator.docChanged(removedMethod.doc_, addedMethod.doc_)) {
                    String sig = methodDiff.newSignature_;
                    if (sig.compareTo("void") == 0)
                        sig = "";
                    String fqName = pkgDiff.name_ + "." + classDiff.name_;
                    String link1 = "<a href=\"" + fqName + HTMLReportGenerator.reportFileExt + "\" class=\"hiddenlink\">";
                    String link2 = "<a href=\"" + fqName + HTMLReportGenerator.reportFileExt + "#" + fqName + "." + addedMethod.name_ + "_changed(" + sig + ")\" class=\"hiddenlink\">";
                    String id = pkgDiff.name_ + "." + classDiff.name_ + ".dmethod." + addedMethod.name_ + "(" + HTMLReportGenerator.simpleName(sig) + ")";
                    String title = link1 + "Class <b>" + classDiff.name_ + "</b></a>, " +
                        link2 +  HTMLReportGenerator.simpleName(methodDiff.newType_) + " <b>" + addedMethod.name_ + "(" + HTMLReportGenerator.simpleName(sig) + ")</b></a>";
                    methodDiff.documentationChange_ = Diff.saveDocDiffs(pkgDiff.name_, classDiff.name_, removedMethod.doc_, addedMethod.doc_, id, title);
                }
                classDiff.methodsChanged.add(methodDiff);
                // Now remove the entries from the remove and add lists
                classDiff.methodsRemoved.remove(startRemoved);
                classDiff.methodsAdded.remove(startAdded);
                if (trace) {
                    System.out.println("Merged the removal and addition of method " + 
                                       removedMethod.name_ + 
                                       " into one change");
                }
            } //if (addedMethod.inheritedFrom_ == null)
        }
    }

    /**
     * Convert multiple removed and added methods into changed methods.
     * This handles the case where the methods' signatures are unchanged, but
     * something else changed.
     */
    public static void mergeMultipleMethods(MethodAPI removedMethod, ClassDiff classDiff, PackageDiff pkgDiff) {
        // Search on the name and signature of the method
        int startRemoved = classDiff.methodsRemoved.indexOf(removedMethod);
        int endRemoved = classDiff.methodsRemoved.lastIndexOf(removedMethod);
        int startAdded = classDiff.methodsAdded.indexOf(removedMethod);
        int endAdded = classDiff.methodsAdded.lastIndexOf(removedMethod);
        if (startRemoved != -1 && endRemoved != -1 && 
            startAdded != -1 && endAdded != -1) {
            // Find the index of the current removed method
            int removedIdx = -1;
            for (int i = startRemoved; i <= endRemoved; i++) {                
                if (removedMethod.equalSignatures(classDiff.methodsRemoved.get(i))) {
                    removedIdx = i;
                    break;
                }
            }
            if (removedIdx == -1) {
                System.out.println("Error: removed method index not found");
                System.exit(5);
            }
            // Find the index of the added method with the same signature, if 
            // it exists, and make sure it is defined locally.
            int addedIdx = -1;
            for (int i = startAdded; i <= endAdded; i++) {
                MethodAPI addedMethod2 = (MethodAPI)(classDiff.methodsAdded.get(i));
                if (addedMethod2.inheritedFrom_ == null &&
                    removedMethod.equalSignatures(addedMethod2))
                    addedIdx = i;
                    break;
            }
            if (addedIdx == -1)
                return;
            MethodAPI addedMethod = (MethodAPI)(classDiff.methodsAdded.get(addedIdx));
            // Create a MemberDiff for this change
            MemberDiff methodDiff = new MemberDiff(removedMethod.name_);
            methodDiff.oldType_ = removedMethod.returnType_;
            methodDiff.newType_ = addedMethod.returnType_;
            methodDiff.oldSignature_ = removedMethod.getSignature();
            methodDiff.newSignature_ = addedMethod.getSignature();
            methodDiff.oldExceptions_ = removedMethod.exceptions_;
            methodDiff.newExceptions_ = addedMethod.exceptions_;
                // The addModifiersChange field may not have been
                // initialized yet if there were multiple methods of the same
                // name.
                diffMethods(methodDiff, removedMethod, addedMethod);
            methodDiff.addModifiersChange(removedMethod.modifiers_.diff(addedMethod.modifiers_));
            // Track changes in documentation
            if (APIComparator.docChanged(removedMethod.doc_, addedMethod.doc_)) {
                String sig = methodDiff.newSignature_;
                if (sig.compareTo("void") == 0)
                    sig = "";
                String fqName = pkgDiff.name_ + "." + classDiff.name_;
                String link1 = "<a href=\"" + fqName + HTMLReportGenerator.reportFileExt + "\" class=\"hiddenlink\">";
                String link2 = "<a href=\"" + fqName + HTMLReportGenerator.reportFileExt + "#" + fqName + "." + addedMethod.name_ + "_changed(" + sig + ")\" class=\"hiddenlink\">";
                String id = pkgDiff.name_ + "." + classDiff.name_ + ".dmethod." + addedMethod.name_ + "(" + HTMLReportGenerator.simpleName(sig) + ")";
                String title = link1 + "Class <b>" + classDiff.name_ + "</b></a>, " +
                    link2 +  HTMLReportGenerator.simpleName(methodDiff.newType_) + " <b>" + addedMethod.name_ + "(" + HTMLReportGenerator.simpleName(sig) + ")</b></a>";
                methodDiff.documentationChange_ = Diff.saveDocDiffs(pkgDiff.name_, classDiff.name_, removedMethod.doc_, addedMethod.doc_, id, title);
            }
            classDiff.methodsChanged.add(methodDiff);
            // Now remove the entries from the remove and add lists
            classDiff.methodsRemoved.remove(removedIdx);
            classDiff.methodsAdded.remove(addedIdx);
            if (trace) {
                System.out.println("Merged the removal and addition of method " + 
                                   removedMethod.name_ + 
                                   " into one change. There were multiple methods of this name.");
            }
        }
    }

    /**
     * Track changes in methods related to abstract, native, and 
     * synchronized modifiers here.
     */
    public static void diffMethods(MemberDiff methodDiff, 
                                   MethodAPI oldMethod, 
                                   MethodAPI newMethod) {
        // Abstract or not
        if (oldMethod.isAbstract_ != newMethod.isAbstract_) {
            String changeText = "";
            if (oldMethod.isAbstract_)
                changeText += "Changed from abstract to non-abstract.";
            else
                changeText += "Changed from non-abstract to abstract.";
            methodDiff.addModifiersChange(changeText);
        }
        // Native or not
        if (Diff.showAllChanges && 
	    oldMethod.isNative_ != newMethod.isNative_) {
            String changeText = "";
            if (oldMethod.isNative_)
                changeText += "Changed from native to non-native.";
            else
                changeText += "Changed from non-native to native.";
            methodDiff.addModifiersChange(changeText);
        }
        // Synchronized or not
        if (Diff.showAllChanges && 
	    oldMethod.isSynchronized_ != newMethod.isSynchronized_) {
            String changeText = "";
            if (oldMethod.isSynchronized_)
                changeText += "Changed from synchronized to non-synchronized.";
            else
                changeText += "Changed from non-synchronized to synchronized.";
            methodDiff.addModifiersChange(changeText);
        }
    }

    /**
     * Convert some removed and added fields into changed fields.
     */
    public static void mergeRemoveAddField(FieldAPI removedField, ClassDiff classDiff, PackageDiff pkgDiff) {
        // Search on the name of the field
        int startRemoved = classDiff.fieldsRemoved.indexOf(removedField);
        int endRemoved = classDiff.fieldsRemoved.lastIndexOf(removedField);
        int startAdded = classDiff.fieldsAdded.indexOf(removedField);
        int endAdded = classDiff.fieldsAdded.lastIndexOf(removedField);
        if (startRemoved != -1 && startRemoved == endRemoved && 
            startAdded != -1 && startAdded == endAdded) {
            // There is only one field with the name of the
            // removedField in both the removed and added fields.
            FieldAPI addedField = (FieldAPI)(classDiff.fieldsAdded.get(startAdded));
            if (addedField.inheritedFrom_ == null) {
                // Create a MemberDiff for this change
                MemberDiff fieldDiff = new MemberDiff(removedField.name_);
                fieldDiff.oldType_ = removedField.type_;
                fieldDiff.newType_ = addedField.type_;
                fieldDiff.addModifiersChange(removedField.modifiers_.diff(addedField.modifiers_));
                // Track changes in documentation
                if (APIComparator.docChanged(removedField.doc_, addedField.doc_)) {
                    String fqName = pkgDiff.name_ + "." + classDiff.name_;
                    String link1 = "<a href=\"" + fqName + HTMLReportGenerator.reportFileExt + "\" class=\"hiddenlink\">";
                    String link2 = "<a href=\"" + fqName + HTMLReportGenerator.reportFileExt + "#" + fqName + "." + addedField.name_ + "\" class=\"hiddenlink\">";
                    String id = pkgDiff.name_ + "." + classDiff.name_ + ".field." + addedField.name_;
                    String title = link1 + "Class <b>" + classDiff.name_ + "</b></a>, " +
                        link2 + HTMLReportGenerator.simpleName(fieldDiff.newType_) + " <b>" + addedField.name_ + "</b></a>";
                    fieldDiff.documentationChange_ = Diff.saveDocDiffs(pkgDiff.name_, classDiff.name_, removedField.doc_, addedField.doc_, id, title);
                }
                classDiff.fieldsChanged.add(fieldDiff);
                // Now remove the entries from the remove and add lists
                classDiff.fieldsRemoved.remove(startRemoved);
                classDiff.fieldsAdded.remove(startAdded);
                if (trace) {
                    System.out.println("Merged the removal and addition of field " + 
                                       removedField.name_ + 
                                       " into one change");
                }
            } //if (addedField.inheritedFrom == null) 
        }
    }

    /** Set to enable increased logging verbosity for debugging. */
    private static boolean trace = false;

}
