/* FichothequeLib_API - Copyright (c) 2013-2025 Vincent Calame - Exemole
 * Logiciel libre donné sous triple licence :
 * 1) selon les termes de la CeCILL V2
 * 2) selon les termes de l’EUPL V.1.1
 * 3) selon les termes de la GNU GPLv3
 * Voir le fichier licences.txt
 */


package net.fichotheque.junction;

import net.fichotheque.SubsetItem;
import net.fichotheque.SubsetKey;


/**
 *
 * @author Vincent Calame
 */
public final class JunctionKey implements Comparable<JunctionKey> {

    private final SubsetKey subsetKey1;
    private final SubsetKey subsetKey2;
    private final int id1;
    private final int id2;

    public JunctionKey(SubsetKey subsetKey1, SubsetKey subsetKey2, int id1, int id2) {
        int compare = subsetKey1.compareTo(subsetKey2);
        if (compare > 0) {
            this.subsetKey2 = subsetKey1;
            this.subsetKey1 = subsetKey2;
            this.id1 = id2;
            this.id2 = id1;
        } else if (compare == 0) {
            this.subsetKey1 = subsetKey1;
            this.subsetKey2 = subsetKey2;
            if (id1 == id2) {
                throw new IllegalArgumentException("SubsetKey and id are the same");
            } else if (id2 < id1) {
                this.id1 = id2;
                this.id2 = id1;
            } else {
                this.id1 = id1;
                this.id2 = id2;
            }
        } else {
            this.subsetKey1 = subsetKey1;
            this.subsetKey2 = subsetKey2;
            this.id1 = id1;
            this.id2 = id2;
        }
    }

    public SubsetKey getSubsetKey1() {
        return subsetKey1;
    }

    public SubsetKey getSubsetKey2() {
        return subsetKey2;
    }

    public int getId1() {
        return id1;
    }

    public int getId2() {
        return id2;
    }

    public int getOrder(SubsetItem subsetItem) {
        SubsetKey subsetKey = subsetItem.getSubsetKey();
        int id = subsetItem.getId();
        if (subsetKey.equals(subsetKey1)) {
            if (id == id1) {
                return 1;
            } else if (subsetKey.equals(subsetKey2)) {
                if (id == id2) {
                    return 2;
                } else {
                    return 0;
                }
            } else {
                return 0;
            }
        } else if (subsetKey.equals(subsetKey2)) {
            if (id == id2) {
                return 2;
            } else {
                return 0;
            }
        } else {
            return 0;
        }
    }

    @Override
    public int hashCode() {
        return subsetKey1.hashCode() * 1000 + id1 * 100 + subsetKey2.hashCode() * 10 + id2;
    }

    @Override
    public boolean equals(Object other) {
        if (other == null) {
            return false;
        }
        if (other == this) {
            return true;
        }
        if (other.getClass() != this.getClass()) {
            return false;
        }
        JunctionKey otherJunctionKey = (JunctionKey) other;
        if (otherJunctionKey.id1 != this.id1) {
            return false;
        }
        if (otherJunctionKey.id2 != this.id2) {
            return false;
        }
        if (!otherJunctionKey.subsetKey1.equals(this.subsetKey1)) {
            return false;
        }
        if (!otherJunctionKey.subsetKey2.equals(this.subsetKey2)) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return subsetKey1 + "/" + id1 + "|" + subsetKey2 + "/" + id2;
    }

    @Override
    public int compareTo(JunctionKey otherJunctionKey) {
        int comp = this.subsetKey1.compareTo(otherJunctionKey.subsetKey1);
        if (comp != 0) {
            return comp;
        }
        comp = this.subsetKey2.compareTo(otherJunctionKey.subsetKey2);
        if (comp != 0) {
            return comp;
        }
        if (this.id1 < otherJunctionKey.id1) {
            return - 1;
        }
        if (this.id1 > otherJunctionKey.id1) {
            return 1;
        }
        if (this.id2 < otherJunctionKey.id2) {
            return - 1;
        }
        if (this.id2 > otherJunctionKey.id2) {
            return 1;
        }
        return 0;
    }

    public static JunctionKey toJunctionKey(SubsetItem subsetItem1, SubsetItem subsetItem2) {
        return new JunctionKey(subsetItem1.getSubsetKey(), subsetItem2.getSubsetKey(), subsetItem1.getId(), subsetItem2.getId());
    }

    public static int getOrder(SubsetItem mainSubsetItem, SubsetItem otherSubsetItem) {
        JunctionKey junctionKey = toJunctionKey(mainSubsetItem, otherSubsetItem);
        return junctionKey.getOrder(mainSubsetItem);
    }

}
