package jp.sourceforge.shovel.exception;

import static jp.sourceforge.shovel.CommonConst.*;

import java.util.Properties;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * エラーページを出力する例外
 */
public class ErrorPage extends RuntimeException {
    private static final long serialVersionUID = -1L;

    //エラーページのレスポンスで返す拡張ヘッダ名
    Properties commonProperties_;
    HttpServletRequest request_;
    HttpServletResponse response_;
    String bundle_;
    String key_;
    String errorCode_;
    String[] causeArgs_ = new String[5];
    String[] counterMeasureArgs_ = new String[5];
    String[] developerInfoArgs_ = new String[5];
    String[] diagnosisArgs_ = new String[5];
    String outputErrorCode_;
    String errorPage_;
    String bundlePrefix_;
    String contentType_;

    public Throwable initCause(Throwable cause) {
        if (contentType_ != null) {
            response_.setContentType(contentType_);
        }
        return super.initCause(cause);
    }
    public String getErrorPage() {
        return errorPage_;
    }
    public void setErrorPage(String errorPage) {
        errorPage_ = errorPage;
    }
    public String getBundlePrefix() {
        return bundlePrefix_;
    }
    public void setBundlePrefix(String bundlePrefix) {
        bundlePrefix_ = bundlePrefix;
    }
    public void setContentType(String contentType) {
        contentType_ = contentType;
    }
    public String getContentType() {
        return contentType_;
    }
    public void setCommonProperties(Properties commonProperties) {
        commonProperties_ = commonProperties;
    }
    public void setRequest(HttpServletRequest request) {
        request_ = request;
    }
    public void setResponse(HttpServletResponse response) {
        response_ = response;
    }
    void setBundle(String bundle) {
        StringBuilder builder = new StringBuilder(getBundlePrefix());
        builder.append(bundle.toLowerCase());
        bundle_ = builder.toString();
    }
    public String getBundle() {
        return bundle_;
    }
    public void setCauseArgs(String[] causeArgs) {
        causeArgs_ = causeArgs;
    }
    public void setCauseArgs(String arg1, String arg2, String arg3, String arg4, String arg5) {
        setCauseArgs(new String[]{arg1, arg2, arg3, arg4, arg5});
    }
    public void setCauseArgs(String arg1, String arg2, String arg3, String arg4) {
        setCauseArgs(arg1, arg2, arg3, arg4, null);
    }
    public void setCauseArgs(String arg1, String arg2, String arg3) {
        setCauseArgs(arg1, arg2, arg3, null);
    }
    public void setCauseArgs(String arg1, String arg2) {
        setCauseArgs(arg1, arg2, null);
    }
    public void setCauseArgs(String arg1) {
        setCauseArgs(arg1, null);
    }
    public String[] getCauseArgs() {
        return causeArgs_;
    }
    public void setCounterMeasureArgs(String[] counterMeasureArgs) {
        counterMeasureArgs_ = counterMeasureArgs;
    }
    public void setCounterMeasureArgs(String arg1, String arg2, String arg3, String arg4, String arg5) {
        setCounterMeasureArgs(new String[]{ arg1, arg2, arg3, arg4, arg5 });
    }
    public void setCounterMeasureArgs(String arg1, String arg2, String arg3, String arg4) {
        setCounterMeasureArgs(arg1, arg2, arg3, arg4, null);
    }
    public void setCounterMeasureArgs(String arg1, String arg2, String arg3) {
        setCounterMeasureArgs(arg1, arg2, arg3, null);
    }
    public void setCounterMeasureArgs(String arg1, String arg2) {
        setCounterMeasureArgs(arg1, arg2, null);
    }
    public void setCounterMeasureArgs(String arg1) {
        setCounterMeasureArgs(arg1, null);
    }
    public String[] getCounterMeasureArgs() {
        return counterMeasureArgs_;
    }
    public void setDeveloperInfoArgs(String[] developerInfoArgs) {
        developerInfoArgs_ = developerInfoArgs;
    }
    public void setDeveloperInfoArgs(String arg1, String arg2, String arg3, String arg4, String arg5) {
        setDeveloperInfoArgs(new String[]{arg1, arg2, arg3, arg4, arg5});
    }
    public void setDeveloperInfoArgs(String arg1, String arg2, String arg3, String arg4) {
        setDeveloperInfoArgs(arg1, arg2, arg3, arg4, null);
    }
    public void setDeveloperInfoArgs(String arg1, String arg2, String arg3) {
        setDeveloperInfoArgs(arg1, arg2, arg3, null);
    }
    public void setDeveloperInfoArgs(String arg1, String arg2) {
        setDeveloperInfoArgs(arg1, arg2, null);
    }
    public void setDeveloperInfoArgs(String arg1) {
        setDeveloperInfoArgs(arg1, null);
    }
    public String[] getDeveloperInfoArgs() {
        return developerInfoArgs_;
    }
    public void setDiagnosisArgs(String[] diagnosisArgs) {
        diagnosisArgs_ = diagnosisArgs;
    }
    public void setDiagnosisArgs(String arg1, String arg2, String arg3, String arg4, String arg5) {
        setDiagnosisArgs(new String[]{arg1, arg2, arg3, arg4, arg5});
    }
    public void setDiagnosisArgs(String arg1, String arg2, String arg3, String arg4) {
        setDiagnosisArgs(arg1, arg2, arg3, arg4, null);
    }
    public void setDiagnosisArgs(String arg1, String arg2, String arg3) {
        setDiagnosisArgs(arg1, arg2, arg3, null);
    }
    public void setDiagnosisArgs(String arg1, String arg2) {
        setDiagnosisArgs(arg1, arg2, null);
    }
    public void setDiagnosisArgs(String arg1) {
        setDiagnosisArgs(arg1, null);
    }
    public String[] getDiagnosisArgs() {
        return diagnosisArgs_;
    }
    public void setErrorCode(String bundle, String key) {
        setBundle(bundle);
        setKey(key);
        StringBuilder builder = new StringBuilder(bundle.toUpperCase());
        builder.append(key);
        errorCode_ = builder.toString();
        response_.addHeader(ERROR_HEADER, errorCode_);
    }
    public void setErrorCode(String bundle, int key) {
        setErrorCode(bundle, String.format("%05d", key));
    }
    public String getErrorCode() {
        return errorCode_;
    }
    public void setOutputErrorCode(String code) {
        outputErrorCode_ = code;
    }
    public String getOutputErrorCode() {
        return outputErrorCode_;
    }
    void setKey(String key) {
        key_ = key;
    }
    public String getKey() {
        return key_;
    }
    public boolean isDebug() {
        String debug = commonProperties_.getProperty("debug");
        return Boolean.valueOf(debug);
    }
    public String[] getSerializedStackTrace() {
        StackTraceElement[] stackTraces = getCause().getStackTrace();
        String[] serialize = new String[stackTraces.length];
        int i = 0;
        for (StackTraceElement stackTrace : stackTraces) {
            serialize[i++] = stackTrace.toString();
        }
        return serialize;
    }
}
