package page.tools.entity;

import org.wikiwebserver.core.Privilege;
import org.wikiwebserver.core.SecurityMan;

/**
 * 
 * @author Michael Gardiner
 *
 */
public abstract class ProtectedStorable extends Storable {
    
    private static final Privilege MODIFY_BY_CODE_PRIVILEGE = Privilege.MODERATOR;
        
    ProtectedStorable() {
        super();
        checkCanModify();
        put("createdTime", new Long(System.currentTimeMillis()));
    }
    
    ProtectedStorable(String id) {
        super(id);
    }
    
    public long getCreatedTime() {
        Long createdTime = (Long) get("createdTime");
        if (createdTime != null) return createdTime.longValue();
        return -1;
    }
    
    public boolean isValid() {
        return super.isValid() && getCreatedTime() > -1;
    }     
    
    public Object get(String key, String... hierarchy) {
        checkCanRead(key, hierarchy);
        return super.get(key, hierarchy);
    } 
    
    public Object remove(String key, String... hierarchy) {
        checkCanModify(key, hierarchy);
        return super.remove(key, hierarchy);
    }      
    
    public Object put(String key, Object value, String... hierarchy) {
        checkCanModify(key, hierarchy);
        return super.put(key, value, hierarchy);
    }     
    
    public long incrementValue(String key, long amount, String... hierarchy) {
        checkCanModify(key, hierarchy);
        return super.incrementValue(key, amount, hierarchy);
    }  
 
    public double recalculateAverage(String key, long amount, String... hierarchy) {
        checkCanModify(key, hierarchy);
        return super.incrementValue(key, amount, hierarchy);
    }     
    
    public void clear() {
        checkCanClear();
        super.clear();
    }

    
    protected void checkCanRead(String key, String... hierarchy) {}
    protected void checkCanReadIndex(String index, String key) {}
    
   
    protected void checkCanModify(String key, String... hierarchy) {
        checkCanModify();  
    }
    
    protected void checkCanModifyIndex(String index, String key) {
        checkCanModify();
    }
    
    protected void checkCanClear() {
        checkCanModify();
    }     

    protected void checkCanModify() {
        Privilege privilege = SecurityMan.getCodePrivilege();
        if (privilege.isBelow(MODIFY_BY_CODE_PRIVILEGE)) {
            throw new SecurityException(privilege.getLabel() +
                      " code is not permitted to modify this entity");
        }
    }
}

