package com.blaazinsoftware.centaur.data.entity;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.googlecode.objectify.Key;
import com.googlecode.objectify.Ref;
import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Id;
import com.googlecode.objectify.annotation.Parent;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * Convenient base class for using Centaur.
 */
@Entity
public abstract class AbstractEntity implements Serializable {

    @Id
    @JsonIgnore
    private Long id;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @Override
    public String toString() {
        if (null == id) {
            return "null";
        }
        return "ID: " + id;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof AbstractEntity) {
            AbstractEntity entity = (AbstractEntity) obj;
            return !(id == null || entity.getId() == null) && (id.equals(entity.getId()));
        }

        return false;
    }

    @Override
    public int hashCode() {
        if (id == null) {
            return 0;
        }
        return id.hashCode();
    }

    public String getWebSafeKey() {
        if (null == id) {
            return null;
        }
        for (Field field : this.getClass().getDeclaredFields()) {
            if (field.isAnnotationPresent(Parent.class)) {
                Object parent = runGetter(field);
                Ref<?> reference = Ref.create(parent);
                return Key.create(reference.key(), this.getClass(), id).toWebSafeString();
            }
        }
        return Key.create(this.getClass(), id).toWebSafeString();
    }

    private Object runGetter(Field field) {
        // Find the correct method
        for (Method method : this.getClass().getMethods()) {
            if ((method.getName().startsWith("get")) && (method.getName().length() == (field.getName().length() + 3))) {
                if (method.getName().toLowerCase().endsWith(field.getName().toLowerCase())) {
                    // Method found, run it
                    try {
                        return method.invoke(this);
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }

                }
            }
        }

        return null;
    }
}

@@ -136,45 +136,8 @@
 ey;%0A
-import com.googlecode.objectify.Ref;%0A
 impo
@@ -234,152 +234,36 @@
 Id;%0A
-import com.googlecode.objectify.annotation.Parent;%0A%0Aimport java.io.Serializable;%0Aimport java.lang.reflect.Field;%0Aimport java.lang.reflect.Method
+%0Aimport java.io.Serializable
 ;%0A%0A/
@@ -1222,1079 +1222,49 @@
     
-for (Field field : this.getClass().getDeclaredFields()) %7B%0A            if (field.isAnnotationPresent(Parent.class)) %7B%0A                Object parent = runGetter(field);%0A                Ref%3C?%3E reference = Ref.create(parent);%0A                return Key.create(reference.key(), this.getClass(), id).toWebSafeString();%0A            %7D%0A        %7D%0A        return Key.create(this.getClass(), id).toWebSafeString();%0A    %7D%0A%0A    private Object runGetter(Field field) %7B%0A        // Find the correct method%0A        for (Method method : this.getClass().getMethods()) %7B%0A            if ((method.getName().startsWith(%22get%22)) && (method.getName().length() == (field.getName().length() + 3))) %7B%0A                if (method.getName().toLowerCase().endsWith(field.getName().toLowerCase())) %7B%0A                    // Method found, run it%0A                    try %7B%0A                        return method.invoke(this);%0A                    %7D catch (Exception e) %7B%0A                        throw new RuntimeException(e);%0A                    %7D%0A%0A                %7D%0A            %7D%0A        %7D%0A%0A        return null
+return Key.create(this).toWebSafeString()
 ;%0A  

Create method to return web safe key.