package com.capgemini.reports.definition.r07report.data.filter.comparators;

import com.capgemini.framework.common.StringHelper;
import com.capgemini.reports.definition.r07report.data.filter.comparators.generics.GenericComparator;
import com.capgemini.reports.definition.r07report.data.filter.comparators.part.PartComparator;
import com.capgemini.reports.exceptions.NotSupportedException;
import com.capgemini.reports.snecmaobjects.ISnecmaObject;

import java.io.Serializable;
import java.util.Comparator;

/**
 * Helper class to comapre two {@link ISnecmaObject}s content.
 */
public abstract class AbstractItemComparator implements Comparator<ISnecmaObject>, Serializable {
    private static final long serialVersionUID = -8787518342193550661L;

    private static int mySafeCmp(final String str1, final String str2) {
        if (str1 == null) {
            return str2 == null ? 0 : 1;
        } else if (str2 == null) {
            return -1;
        } else {
            return str1.compareTo(str2);
        }
    }

    /**
     * Compares two Receptors together. Only their item ID and Name are compared.
     *
     * @param thisObj  this object
     * @param otherObj an other object
     * @return the diff
     */
    static int compareReceptors(final ISnecmaObject thisObj, final ISnecmaObject otherObj) {
        String thisType = thisObj.getType();
        String otherType = otherObj.getType();
        int cmp = thisType.compareTo(otherType);
        if (cmp != 0) {
            return cmp;
        }
        // Compare basic data
        cmp = mySafeCmp(thisObj.getItemId(), otherObj.getItemId());
        if (cmp != 0) {
            return cmp;
        }
        cmp = mySafeCmp(thisObj.getName(), otherObj.getName());
        return cmp;
    }

    /**
     * Compares two components's contents. The components can be any Part or any Generic.
     *
     * @param thisComponent  this object
     * @param otherComponent an other object
     * @return the diff
     * @throws NotSupportedException if objects are of the wrong type
     */
    public static int compareComponents(final ISnecmaObject thisComponent, final ISnecmaObject otherComponent) throws NotSupportedException {
        String thisType = thisComponent.getType();
        String otherType = otherComponent.getType();
        int cmp = thisType.compareTo(otherType);
        if (cmp != 0) {
            return cmp;
        }
        if (thisComponent.isGeneric()) {
            return GenericComparator.compareGenerics(thisComponent, otherComponent);
        }
        if (thisComponent.isPart()) {
            return PartComparator.compareParts(thisComponent, otherComponent);
        } else {
            throw new NotSupportedException(
                    StringHelper.concat("Unsupported Component type: ", thisComponent.getItemId(), " of type ", thisType).toString());
        }
    }

    protected int safeCmp(final String str1, final String str2) {
        return mySafeCmp(str1, str2);
    }
}
