package ch.usi.dag.dislreserver.shadow;

import java.util.Formattable;
import java.util.Formatter;

public class ShadowObject implements Formattable {

    final private long netRef;
    final private long shadowId;
    final private ShadowClass shadowClass;

    private Object shadowState;

    //


    ShadowObject (final long netReference, final ShadowClass shadowClass) {
        this.netRef = netReference;
        this.shadowId = NetReferenceHelper.get_object_id (netReference);
        this.shadowClass = shadowClass;
        this.shadowState = null;
    }

    //

    public long getNetRef () {
        return netRef;
    }

    public long getId () {
        return shadowId;
    }

    public ShadowClass getShadowClass() {

        if (shadowClass != null) {
            return shadowClass;
        } else {

            if (equals(ShadowClassTable.BOOTSTRAP_CLASSLOADER)) {
                throw new NullPointerException();
            }

            return ShadowClassTable.JAVA_LANG_CLASS;
        }
    }

    public synchronized Object getState () {
        return shadowState;
    }


    public synchronized <T> T getState (final Class <T> type) {
        return type.cast (shadowState);
    }


    public synchronized void setState (final Object shadowState) {
        this.shadowState = shadowState;
    }

    public synchronized Object setStateIfAbsent(Object shadowState) {

        Object retVal = this.shadowState;

        if (retVal == null) {
            this.shadowState = shadowState;
        }

        return retVal;
    }

    // only object id considered
    // TODO consider also the class ID
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + (int) (shadowId ^ (shadowId >>> 32));
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof ShadowObject) {
            return shadowId == ((ShadowObject) obj).shadowId;
        }

        return false;
    }

    //

    @Override
    public void formatTo (
        final Formatter formatter,
        final int flags, final int width, final int precision
    ) {
        formatter.format ("%s@%x", (shadowClass != null) ? shadowClass.getName () : "<missing>", shadowId);
    }

}

@@ -1625,16 +1625,30 @@
 lass ID%0A
+    @Override%0A
     publ
@@ -1679,85 +1679,17 @@
     
-final int prime = 31;%0A        int result = 1;%0A        result = prime * result
+return 31
  + (
@@ -1729,31 +1729,8 @@
 ));%0A
-        return result;%0A
     
@@ -1845,28 +1845,34 @@
     
-return shadowId =
+final ShadowObject that 
 = 
-(
 (Sha
@@ -1889,18 +1889,55 @@
  obj
-).shadowId
+;%0A            return this.netRef == that.netRef
 ;%0A  

use the whole object tag (a.k.a. net reference) instead of just object id to compare for equality. ShadowObject: simplify the hash code calculation.