package it.mice.voila.runtime.security;

import it.mice.voila.runtime.util.StringUtils;

import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.intercept.RunAsManager;

/**
 * Created by IntelliJ IDEA.
 * User: zzy9v4
 * Date: 7-giu-2006
 * Time: 17.29.40
 * To change this template use File | Settings | File Templates.
 */
public class OperationConfigAttribute implements ConfigAttribute {
	public static final String AUTHORIZATION_RULE_TYPE_PROCESS = "P";
	public static final String AUTHORIZATION_RULE_TYPE_RENDER = "R";
	public static final String AUTHORIZATION_RULE_TYPE_BOTH = "B";
	
    private String applicationId;
    private int operationId;
    private String operationName;
    private String operationProps;
    private String authorizationRule;
    private String authorizationRuleRender;
    private String authorizationRuleType;
    private String allowDeniedFlag;
    private String msgKey;
    private String msgText;
    private String auditData;
    private boolean isAuditEnabled;

    private OperationPerProfileConfigAttribute[] profiles;

    public OperationConfigAttribute() {
	}

    public OperationConfigAttribute(String operationName, String profileList) {
        this.operationName = operationName;
        setProfileList(profileList);
	}

	public OperationConfigAttribute(
                        String applicationId,
                        int operationId,
                        String operationName,
                        String operationProps,
                        String authorizationRule,
                        String allowDeniedFlag,
                        String msgKey,
                        String msgText,
                        String auditingFlag,
                        String auditingData) {
        this.applicationId = applicationId;
        this.operationId = operationId;
        this.operationName = operationName;
        this.operationProps = StringUtils.convertToProperties(operationProps);
        this.authorizationRule = authorizationRule;
        this.allowDeniedFlag = allowDeniedFlag;
        this.msgKey = msgKey;
        this.msgText = msgText;
        if (auditingFlag != null && auditingFlag.equalsIgnoreCase("Y")) {
            this.auditData = auditingData;
            this.isAuditEnabled = true;
        } else {
            this.isAuditEnabled = false;
        }
        this.authorizationRuleType = AUTHORIZATION_RULE_TYPE_PROCESS;
    }

	public void setProfileList(String profileList) {
        String[] profileArray = profileList.split("\\,");
    	this.profiles = new OperationPerProfileConfigAttribute[profileArray.length];
    	for (int i = 0; i < profileArray.length; i++) {
    		this.profiles[i] = new OperationPerProfileConfigAttribute(fixProfileName(profileArray[i]), null, null, null, null);
		}
	}
	
    private String fixProfileName(String profile) {
		return profile.startsWith("ROLE_") ? profile : "ROLE_" + profile;
	}

	public String getOperationName() {
        return operationName;
    }

    public void setOperationName(String operationName) {
        this.operationName = operationName;
    }

    public String getOperationProps() {
        return operationProps;
    }

    public void setOperationProps(String operationProps) {
        this.operationProps = operationProps;
    }

    public String getAuthorizationRule() {
        return authorizationRule;
    }

    public void setAuthorizationRule(String authorizationRule) {
        this.authorizationRule = authorizationRule;
    }

    public String getAuthorizationRuleRender() {
        return authorizationRuleRender;
    }

    public void setAuthorizationRuleRender(String authorizationRule) {
        this.authorizationRuleRender = authorizationRule;
    }

    /**
	 * @return the authorizationRuleType
	 */
	public String getAuthorizationRuleType() {
		return authorizationRuleType;
	}

	/**
	 * @param authorizationRuleType the authorizationRuleType to set
	 */
	public void setAuthorizationRuleType(String authorizationRuleType) {
		this.authorizationRuleType = authorizationRuleType;
	}

	public boolean isAuthorizationRuleTypeRender() {
		return AUTHORIZATION_RULE_TYPE_RENDER.equals(getAuthorizationRuleType()) || AUTHORIZATION_RULE_TYPE_BOTH.equals(getAuthorizationRuleType());
	}

	public boolean isAuthorizationRuleTypeProcess() {
		return AUTHORIZATION_RULE_TYPE_PROCESS.equals(getAuthorizationRuleType()) || AUTHORIZATION_RULE_TYPE_BOTH.equals(getAuthorizationRuleType());
	}

	public boolean isAuthorizationRuleTypeBoth() {
		return AUTHORIZATION_RULE_TYPE_BOTH.equals(getAuthorizationRuleType());
	}
	
	public String getAllowDeniedFlag() {
        return allowDeniedFlag;
    }

    public void setAllowDeniedFlag(String allowDeniedFlag) {
        this.allowDeniedFlag = allowDeniedFlag;
    }

    public OperationPerProfileConfigAttribute[] getProfiles() {
        return profiles;
    }

    public void setProfiles(OperationPerProfileConfigAttribute[] profiles) {
        this.profiles = profiles;
    }

    public String getMsgKey() {
        return msgKey;
    }

    public void setMsgKey(String msgKey) {
        this.msgKey = msgKey;
    }

    public String getMsgText() {
        return msgText;
    }

    public void setMsgText(String msgText) {
        this.msgText = msgText;
    }

    public String getAuditData() {
        return auditData;
    }

    public void setAuditData(String auditData) {
        this.auditData = auditData;
    }

    public boolean isAuditEnabled() {
        return isAuditEnabled;
    }

    public void setAuditEnabled(boolean auditEnabled) {
        isAuditEnabled = auditEnabled;
    }

    public String getApplicationId() {
        return applicationId;
    }

    public void setApplicationId(String applicationId) {
        this.applicationId = applicationId;
    }

    public int getOperationId() {
        return operationId;
    }

    public void setOperationId(int operationId) {
        this.operationId = operationId;
    }

    /**
     * If the <code>ConfigAttribute</code> can be represented as a <code>String</code> and that
     * <code>String</code> is sufficient in precision to be relied upon as a configuration parameter by a 
     * {RunAsManager}, {AccessDecisionManager} or <code>AccessDecisionManager</code> delegate, this method should
     * return such a <code>String</code>.<p>If the <code>ConfigAttribute</code> cannot be expressed with
     * sufficient precision as a <code>String</code>,  <code>null</code> should be returned. Returning
     * <code>null</code> will require any relying classes to specifically support the  <code>ConfigAttribute</code>
     * implementation, so returning  <code>null</code> should be avoided unless actually  required.</p>
     *
     * @return a representation of the configuration attribute (or <code>null</code> if the configuration attribute
     *         cannot be expressed as a <code>String</code> with sufficient precision).
     */
    public String getAttribute() {
        return null;
    }

    public String toString() {
        StringBuffer sb = new StringBuffer();
        sb.append(super.toString()).append(": ");
        sb.append("applicationId: ").append(this.applicationId).append("; ");
        sb.append("operationId: ").append(this.operationId).append("; ");
        sb.append("operationName: ").append(this.operationName).append("; ");
        sb.append("operationProps: ").append(this.operationProps).append("; ");
        sb.append("authorizationRule: ").append(this.authorizationRule).append("; ");
        sb.append("authorizationRuleRender: ").append(this.authorizationRuleRender).append("; ");
        sb.append("allowDeniedFlag: ").append(this.allowDeniedFlag).append("; ");
        sb.append("msgKey: ").append(this.msgKey).append("; ");
        sb.append("msgText: ").append(this.msgText).append("; ");
        sb.append("isAuditEnabled: ").append(this.isAuditEnabled).append("; ");
        sb.append("auditData: ").append(this.auditData).append("; ");

        if (this.getProfiles() != null) {
            sb.append("Granted Authorities: ");

            for (int i = 0; i < this.getProfiles().length; i++) {
                if (i > 0) {
                    sb.append(", ");
                }

                sb.append(this.getProfiles()[i].toString());
            }
        } else {
            sb.append("Not granted any authorities");
        }

        return sb.toString();
    }
}
