/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.dx.util;

import java.io.PrintStream;
import java.io.PrintWriter;

/**
 * Exception which carries around structured context.
 */
public class ExceptionWithContext
        extends RuntimeException {
    /** {@code non-null;} human-oriented context of the exception */
    private StringBuffer context;

    /**
     * Augments the given exception with the given context, and return the
     * result. The result is either the given exception if it was an
     * {@link ExceptionWithContext}, or a newly-constructed exception if it
     * was not.
     *
     * @param ex {@code non-null;} the exception to augment
     * @param str {@code non-null;} context to add
     * @return {@code non-null;} an appropriate instance
     */
    public static ExceptionWithContext withContext(Throwable ex, String str) {
        ExceptionWithContext ewc;

        if (ex instanceof ExceptionWithContext) {
            ewc = (ExceptionWithContext) ex;
        } else {
            ewc = new ExceptionWithContext(ex);
        }

        ewc.addContext(str);
        return ewc;
    }

    /**
     * Constructs an instance.
     *
     * @param message human-oriented message
     */
    public ExceptionWithContext(String message) {
        this(message, null);
    }

    /**
     * Constructs an instance.
     *
     * @param cause {@code null-ok;} exception that caused this one
     */
    public ExceptionWithContext(Throwable cause) {
        this(null, cause);
    }

    /**
     * Constructs an instance.
     *
     * @param message human-oriented message
     * @param cause {@code null-ok;} exception that caused this one
     */
    public ExceptionWithContext(String message, Throwable cause) {
        super((message != null) ? message :
              (cause != null) ? cause.getMessage() : null,
              cause);

        if (cause instanceof ExceptionWithContext) {
            String ctx = ((ExceptionWithContext) cause).context.toString();
            context = new StringBuffer(ctx.length() + 200);
            context.append(ctx);
        } else {
            context = new StringBuffer(200);
        }
    }

    /** {@inheritDoc} */
    @Override
    public void printStackTrace(PrintStream out) {
        super.printStackTrace(out);
        out.println(context);
    }

    /** {@inheritDoc} */
    @Override
    public void printStackTrace(PrintWriter out) {
        super.printStackTrace(out);
        out.println(context);
    }

    /**
     * Adds a line of context to this instance.
     *
     * @param str {@code non-null;} new context
     */
    public void addContext(String str) {
        if (str == null) {
            throw new NullPointerException("str == null");
        }

        context.append(str);
        if (!str.endsWith("\n")) {
            context.append('\n');
        }
    }

    /**
     * Gets the context.
     *
     * @return {@code non-null;} the context
     */
    public String getContext() {
        return context.toString();
    }

    /**
     * Prints the message and context.
     *
     * @param out {@code non-null;} where to print to
     */
    public void printContext(PrintStream out) {
        out.println(getMessage());
        out.print(context);
    }

    /**
     * Prints the message and context.
     *
     * @param out {@code non-null;} where to print to
     */
    public void printContext(PrintWriter out) {
        out.println(getMessage());
        out.print(context);
    }
}
