/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.apache.drill.common.exceptions;

import static java.lang.Thread.sleep;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.lang.management.ManagementFactory;

import org.apache.drill.exec.proto.CoordinationProtos;
import org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint;
import org.apache.drill.exec.proto.UserBitShared.DrillPBError;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
 * Base class for all user exception. The goal is to separate out common error conditions where we can give users
 * useful feedback.
 * <p>Throwing a user exception will guarantee it's message will be displayed to the user, along with any context
 * information added to the exception at various levels while being sent to the client.
 * <p>A specific class of user exceptions are system exception. They represent system level errors that don't display
 * any specific error message to the user apart from "A system error has occurred" along with information to retrieve
 * the details of the exception from the logs.
 * <p>Although system exception should only display a generic message to the user, for now they will display the root
 * error message, until all user errors are properly sent from the server side.
 * <p>Any thrown exception that is not wrapped inside a user exception will automatically be converted to a system
 * exception before being sent to the client.
 *
 * @see org.apache.drill.exec.proto.UserBitShared.DrillPBError.ErrorType
 */
public class UserException extends DrillRuntimeException {
  private static final long serialVersionUID = -6720929331624621840L;
  private static final Logger logger = LoggerFactory.getLogger(UserException.class);

  public static final String MEMORY_ERROR_MSG = "One or more nodes ran out of memory while executing the query.";

  /**
   * Creates a RESOURCE error with a prebuilt message for out of memory exceptions
   *
   * @param cause exception that will be wrapped inside a memory error
   * @return resource error builder
   */
  public static Builder memoryError(final Throwable cause) {
    return UserException.resourceError(cause)
      .message(MEMORY_ERROR_MSG).addContext(cause.getMessage());
  }

  public static Builder memoryError(final String format, final Object... args) {
    final Builder builder =  UserException.resourceError();
    builder.message(MEMORY_ERROR_MSG);
    if (!format.isEmpty()) {
      builder.addContext(String.format(format, args));
    }
    return builder;
  }

  /**
   * Creates a RESOURCE error with a prebuilt message for out of memory exceptions
   *
   * @return resource error builder
   */
  public static Builder memoryError() {
    return memoryError("");
  }

  /**
   * Wraps the passed exception inside a system error.
   * <p>The cause message will be used unless {@link Builder#message(String, Object...)} is called.
   * <p>If the wrapped exception is, or wraps, a user exception it will be returned by {@link Builder#build(Logger)}
   * instead of creating a new exception. Any added context will be added to the user exception as well.
   *
   * @see org.apache.drill.exec.proto.UserBitShared.DrillPBError.ErrorType#SYSTEM
   *
   * @param cause exception we want the user exception to wrap. If cause is, or wraps, a user exception it will be
   *              returned by the builder instead of creating a new user exception
   * @return user exception builder
   */

  public static Builder systemError(final Throwable cause) {
    return new Builder(DrillPBError.ErrorType.SYSTEM, cause);
  }

  /**
   * Creates a new user exception builder.
   *
   * @see org.apache.drill.exec.proto.UserBitShared.DrillPBError.ErrorType#CONNECTION
   * @return user exception builder
   */
  public static Builder connectionError() {
    return connectionError(null);
  }

  /**
   * Wraps the passed exception inside a connection error.
   * <p>The cause message will be used unless {@link Builder#message(String, Object...)} is called.
   * <p>If the wrapped exception is, or wraps, a user exception it will be returned by {@link Builder#build(Logger)}
   * instead of creating a new exception. Any added context will be added to the user exception as well.
   *
   * @see org.apache.drill.exec.proto.UserBitShared.DrillPBError.ErrorType#CONNECTION
   *
   * @param cause exception we want the user exception to wrap. If cause is, or wraps, a user exception it will be
   *              returned by the builder instead of creating a new user exception
   * @return user exception builder
   */
  public static Builder connectionError(final Throwable cause) {
    return new Builder(DrillPBError.ErrorType.CONNECTION, cause);
  }

  /**
   * Creates a new user exception builder.
   *
   * @see org.apache.drill.exec.proto.UserBitShared.DrillPBError.ErrorType#DATA_READ
   * @return user exception builder
   */
  public static Builder dataReadError() {
    return dataReadError(null);
  }

  /**
   * Wraps the passed exception inside a data read error.
   * <p>The cause message will be used unless {@link Builder#message(String, Object...)} is called.
   * <p>If the wrapped exception is, or wraps, a user exception it will be returned by {@link Builder#build(Logger)}
   * instead of creating a new exception. Any added context will be added to the user exception as well.
   *
   * @see org.apache.drill.exec.proto.UserBitShared.DrillPBError.ErrorType#DATA_READ
   *
   * @param cause exception we want the user exception to wrap. If cause is, or wraps, a user exception it will be
   *              returned by the builder instead of creating a new user exception
   * @return user exception builder
   */
  public static Builder dataReadError(final Throwable cause) {
    return new Builder(DrillPBError.ErrorType.DATA_READ, cause);
  }

  /**
   * Creates a new user exception builder .
   *
   * @see org.apache.drill.exec.proto.UserBitShared.DrillPBError.ErrorType#DATA_WRITE
   * @return user exception builder
   */
  public static Builder dataWriteError() {
    return dataWriteError(null);
  }

  /**
   * Wraps the passed exception inside a data write error.
   * <p>The cause message will be used unless {@link Builder#message(String, Object...)} is called.
   * <p>If the wrapped exception is, or wraps, a user exception it will be returned by {@link Builder#build(Logger)}
   * instead of creating a new exception. Any added context will be added to the user exception as well.
   *
   * @see org.apache.drill.exec.proto.UserBitShared.DrillPBError.ErrorType#DATA_WRITE
   *
   * @param cause exception we want the user exception to wrap. If cause is, or wraps, a user exception it will be
   *              returned by the builder instead of creating a new user exception
   * @return user exception builder
   */
  public static Builder dataWriteError(final Throwable cause) {
    return new Builder(DrillPBError.ErrorType.DATA_WRITE, cause);
  }

  /**
   * Creates a new user exception builder .
   *
   * @see org.apache.drill.exec.proto.UserBitShared.DrillPBError.ErrorType#FUNCTION
   * @return user exception builder
   */
  public static Builder functionError() {
    return functionError(null);
  }

  /**
   * Wraps the passed exception inside a function error.
   * <p>The cause message will be used unless {@link Builder#message(String, Object...)} is called.
   * <p>If the wrapped exception is, or wraps, a user exception it will be returned by {@link Builder#build(Logger)}
   * instead of creating a new exception. Any added context will be added to the user exception as well.
   *
   * @see org.apache.drill.exec.proto.UserBitShared.DrillPBError.ErrorType#FUNCTION
   *
   * @param cause exception we want the user exception to wrap. If cause is, or wraps, a user exception it will be
   *              returned by the builder instead of creating a new user exception
   * @return user exception builder
   */
  public static Builder functionError(final Throwable cause) {
    return new Builder(DrillPBError.ErrorType.FUNCTION, cause);
  }

  /**
   * Creates a new user exception builder .
   *
   * @see org.apache.drill.exec.proto.UserBitShared.DrillPBError.ErrorType#PARSE
   * @return user exception builder
   */
  public static Builder parseError() {
    return parseError(null);
  }

  /**
   * Wraps the passed exception inside a parse error.
   * <p>The cause message will be used unless {@link Builder#message(String, Object...)} is called.
   * <p>If the wrapped exception is, or wraps, a user exception it will be returned by {@link Builder#build(Logger)}
   * instead of creating a new exception. Any added context will be added to the user exception as well.
   *
   * @see org.apache.drill.exec.proto.UserBitShared.DrillPBError.ErrorType#PARSE
   *
   * @param cause exception we want the user exception to wrap. If cause is, or wraps, a user exception it will be
   *              returned by the builder instead of creating a new user exception
   * @return user exception builder
   */
  public static Builder parseError(final Throwable cause) {
    return new Builder(DrillPBError.ErrorType.PARSE, cause);
  }

  /**
   * Creates a new user exception builder .
   *
   * @see org.apache.drill.exec.proto.UserBitShared.DrillPBError.ErrorType#VALIDATION
   * @return user exception builder
   */
  public static Builder validationError() {
    return validationError(null);
  }

  /**
   * wraps the passed exception inside a validation error.
   * <p>the cause message will be used unless {@link Builder#message(String, Object...)} is called.
   * <p>if the wrapped exception is, or wraps, a user exception it will be returned by {@link Builder#build(Logger)}
   * instead of creating a new exception. Any added context will be added to the user exception as well.
   *
   * @see org.apache.drill.exec.proto.UserBitShared.DrillPBError.ErrorType#VALIDATION
   *
   * @param cause exception we want the user exception to wrap. If cause is, or wraps, a user exception it will be
   *              returned by the builder instead of creating a new user exception
   * @return user exception builder
   */
  public static Builder validationError(Throwable cause) {
    return new Builder(DrillPBError.ErrorType.VALIDATION, cause);
  }

  /**
   * creates a new user exception builder .
   *
   * @see org.apache.drill.exec.proto.UserBitShared.DrillPBError.ErrorType#PERMISSION
   * @return user exception builder
   */
  public static Builder permissionError() {
    return permissionError(null);
  }

  /**
   * Wraps the passed exception inside a permission error.
   * <p>The cause message will be used unless {@link Builder#message(String, Object...)} is called.
   * <p>If the wrapped exception is, or wraps, a user exception it will be returned by {@link Builder#build(Logger)}
   * instead of creating a new exception. Any added context will be added to the user exception as well.
   *
   * @see org.apache.drill.exec.proto.UserBitShared.DrillPBError.ErrorType#PERMISSION
   *
   * @param cause exception we want the user exception to wrap. If cause is, or wraps, a user exception it will be
   *              returned by the builder instead of creating a new user exception
   * @return user exception builder
   */
  public static Builder permissionError(final Throwable cause) {
    return new Builder(DrillPBError.ErrorType.PERMISSION, cause);
  }

  /**
   * Creates a new user exception builder .
   *
   * @see org.apache.drill.exec.proto.UserBitShared.DrillPBError.ErrorType#PLAN
   * @return user exception builder
   */
  public static Builder planError() {
    return planError(null);
  }

  /**
   * Wraps the passed exception inside a plan error.
   * <p>The cause message will be used unless {@link Builder#message(String, Object...)} is called.
   * <p>If the wrapped exception is, or wraps, a user exception it will be returned by {@link Builder#build(Logger)}
   * instead of creating a new exception. Any added context will be added to the user exception as well.
   *
   * @see org.apache.drill.exec.proto.UserBitShared.DrillPBError.ErrorType#PLAN
   *
   * @param cause exception we want the user exception to wrap. If cause is, or wraps, a user exception it will be
   *              returned by the builder instead of creating a new user exception
   * @return user exception builder
   */
  public static Builder planError(final Throwable cause) {
    return new Builder(DrillPBError.ErrorType.PLAN, cause);
  }

  /**
   * Wraps the passed exception inside a plugin error.
   * <p>The cause message will be used unless {@link Builder#message(String, Object...)} is called.
   * <p>If the wrapped exception is, or wraps, a user exception it will be returned by
   * {@link Builder#build(Logger)}
   * instead of creating a new exception. Any added context will be added to the user exception
   * as well.
   *
   * @see org.apache.drill.exec.proto.UserBitShared.DrillPBError.ErrorType#PLUGIN
   *
   * @param cause exception we want the user exception to wrap. If cause is, or wraps, a user
   * exception it will be returned by the builder instead of creating a new user exception
   * @return user exception builder
   */
  public static Builder pluginError(final Throwable cause) {
    return new Builder(DrillPBError.ErrorType.PLUGIN, cause);
  }

  /**
   * Creates a new user exception builder .
   *
   * @see org.apache.drill.exec.proto.UserBitShared.DrillPBError.ErrorType#RESOURCE
   * @return user exception builder
   */
  public static Builder resourceError() {
    return resourceError(null);
  }

  /**
   * Wraps the passed exception inside a resource error.
   * <p>The cause message will be used unless {@link Builder#message(String, Object...)} is called.
   * <p>If the wrapped exception is, or wraps, a user exception it will be returned by {@link Builder#build(Logger)}
   * instead of creating a new exception. Any added context will be added to the user exception as well.
   *
   * @see org.apache.drill.exec.proto.UserBitShared.DrillPBError.ErrorType#RESOURCE
   *
   * @param cause exception we want the user exception to wrap. If cause is, or wraps, a user exception it will be
   *              returned by the builder instead of creating a new user exception
   * @return user exception builder
   */
  public static Builder resourceError(final Throwable cause) {
    return new Builder(DrillPBError.ErrorType.RESOURCE, cause);
  }

  /**
   * Creates a new user exception builder .
   *
   * @see org.apache.drill.exec.proto.UserBitShared.DrillPBError.ErrorType#UNSUPPORTED_OPERATION
   * @return user exception builder
   */
  public static Builder unsupportedError() {
    return unsupportedError(null);
  }

  /**
   * Wraps the passed exception inside a unsupported error.
   * <p>The cause message will be used unless {@link Builder#message(String, Object...)} is called.
   * <p>If the wrapped exception is, or wraps, a user exception it will be returned by {@link Builder#build(Logger)}
   * instead of creating a new exception. Any added context will be added to the user exception as well.
   *
   * @see org.apache.drill.exec.proto.UserBitShared.DrillPBError.ErrorType#UNSUPPORTED_OPERATION
   *
   * @param cause exception we want the user exception to wrap. If cause is, or wraps, a user exception it will be
   *              returned by the builder instead of creating a new user exception
   * @return user exception builder
   */
  public static Builder unsupportedError(final Throwable cause) {
    return new Builder(DrillPBError.ErrorType.UNSUPPORTED_OPERATION, cause);
  }

  /**
   * Report an unsupported schema change.
   *
   * @param cause the <tt>SchemaChangeException</tt>. (Not typed because that
   * class is not visible to this package.)
   * @return user exception builder.
   */
  public static Builder schemaChangeError(final Throwable cause) {
    return new Builder(DrillPBError.ErrorType.UNSUPPORTED_OPERATION, cause)
        .addContext("Unsupported schema change");
  }

  public static Builder schemaChangeError() {
    return schemaChangeError(null);
  }

  /**
   * Wraps an error that arises from execution due to issues in the query, in
   * the environment and so on -- anything other than "this should never occur"
   * type checks.
   * @param cause exception we want the user exception to wrap. If cause is, or wraps, a user exception it will be
   *              returned by the builder instead of creating a new user exception
   * @return user exception builder
   */

  public static Builder executionError(final Throwable cause) {
    return new Builder(DrillPBError.ErrorType.EXECUTION_ERROR, cause);
  }

  /**
   * Indicates an internal validation failed or similar unexpected error. Indicates
   * the problem is likely within Drill itself rather than due to the environment,
   * query, etc.
   * @param cause exception we want the user exception to wrap. If cause is, or wraps, a user exception it will be
   *              returned by the builder instead of creating a new user exception
   * @return user exception builder
   */

  public static Builder internalError(final Throwable cause) {
    return new Builder(DrillPBError.ErrorType.INTERNAL_ERROR, cause);
  }

  public static Builder internalError() {
    return new Builder(DrillPBError.ErrorType.INTERNAL_ERROR, null);
  }

  /**
   * Indicates an unspecified error: code caught the exception, but does not have
   * visibility into the cause well enough to pick one of the more specific
   * error types. In practice, using this exception indicates that error handling
   * should be moved closer to the source of the exception so we can provide the
   * user with a better explanation than "something went wrong."
   * @param cause exception we want the user exception to wrap. If cause is, or wraps, a user exception it will be
   *              returned by the builder instead of creating a new user exception
   * @return user exception builder
   */
  public static Builder unspecifiedError(final Throwable cause) {
    return new Builder(DrillPBError.ErrorType.UNSPECIFIED_ERROR, cause);
  }

  /**
   * Builder class for DrillUserException. You can wrap an existing exception, in this case it will first check if
   * this exception is, or wraps, a DrillUserException. If it does then the builder will use the user exception as it is
   * (it will ignore the message passed to the constructor) and will add any additional context information to the
   * exception's context
   */
  public static class Builder {

    private final Throwable cause;
    private final DrillPBError.ErrorType errorType;
    private final UserException uex;
    private final UserExceptionContext context;

    private String message;

    /**
     * Wraps an existing exception inside a user exception.
     *
     * @param errorType user exception type that should be created if the passed exception isn't,
     *                  or doesn't wrap a user exception
     * @param cause exception to wrap inside a user exception. Can be null
     */
    private Builder(final DrillPBError.ErrorType errorType, final Throwable cause) {
      this.cause = cause;

      //TODO handle the improbable case where cause is a SYSTEM exception ?
      uex = ErrorHelper.findWrappedUserException(cause);
      if (uex != null) {
        this.errorType = null;
        this.context = uex.context;
      } else {
        // we will create a new user exception
        this.errorType = errorType;
        this.context = new UserExceptionContext();
        this.message = cause != null ? cause.getMessage() : null;
      }
    }

    private Builder(UserException uex) {
      this.uex = uex;
      cause = uex.getCause();
      errorType = uex.errorType;
      context = uex.context;
      message = uex.getOriginalMessage();
    }

    /**
     * sets or replaces the error message.
     * <p>This will be ignored if this builder is wrapping a user exception
     *
     * @see String#format(String, Object...)
     *
     * @param format format string
     * @param args Arguments referenced by the format specifiers in the format string
     * @return this builder
     */
    public Builder message(final String format, final Object... args) {
      // we can't replace the message of a user exception
      if (uex == null && format != null) {
        if (args.length == 0) {
          message = format;
        } else {
          message = String.format(format, args);
        }
      }
      return this;
    }

    /**
     * add DrillbitEndpoint identity to the context.
     * <p>if the context already has a drillbitEndpoint identity, the new identity will be ignored
     *
     * @param endpoint drillbit endpoint identity
     */
    public Builder addIdentity(final CoordinationProtos.DrillbitEndpoint endpoint) {
      context.add(endpoint);
      return this;
    }

    /**
     * add a string line to the bottom of the context
     * @param value string line
     * @return this builder
     */
    public Builder addContext(final String value) {
      context.add(value);
      return this;
    }

    /**
     * add a string line to the bottom of the context
     * @param value string line
     * @return this builder
     */
    public Builder addContext(final String value, Object... args) {
      context.add(String.format(value, args));
      return this;
    }

    /**
     * add a string value to the bottom of the context
     *
     * @param name context name
     * @param value context value
     * @return this builder
     */
    public Builder addContext(final String name, final String value) {
      context.add(name, value);
      return this;
    }

    /**
     * add a long value to the bottom of the context
     *
     * @param name context name
     * @param value context value
     * @return this builder
     */
    public Builder addContext(final String name, final long value) {
      context.add(name, value);
      return this;
    }

    /**
     * add a double value to the bottom of the context
     *
     * @param name context name
     * @param value context value
     * @return this builder
     */
    public Builder addContext(final String name, final double value) {
      context.add(name, value);
      return this;
    }

    public Builder addContext(CustomErrorContext context) {
      if (context != null) {
        context.addContext(this);
      }
      return this;
    }

    /**
     * pushes a string value to the top of the context
     *
     * @param value context value
     * @return this builder
     */
    public Builder pushContext(final String value) {
      context.push(value);
      return this;
    }

    /**
     * pushes a string value to the top of the context
     *
     * @param name context name
     * @param value context value
     * @return this builder
     */
    public Builder pushContext(final String name, final String value) {
      context.push(name, value);
      return this;
    }

    /**
     * pushes a long value to the top of the context
     *
     * @param name context name
     * @param value context value
     * @return this builder
     */
    public Builder pushContext(final String name, final long value) {
      context.push(name, value);
      return this;
    }

    /**
     * pushes a double value to the top of the context
     *
     * @param name context name
     * @param value context value
     * @return this builder
     */
    public Builder pushContext(final String name, final double value) {
      context.push(name, value);
      return this;
    }

    private static final File SPIN_FILE =  new File("/tmp/drill/spin");
    /**
     * builds a user exception or returns the wrapped one. If the error is a system error, the error message is logged
     * to the given {@link Logger}.
     *
     * @param logger the logger to write to
     * @return user exception
     */
    public UserException build(final Logger logger) {

      // To allow for debugging:
      //
      // A spinner code to make the execution stop here while the file '/tmp/drill/spin' exists
      // Can be used to attach a debugger, use jstack, etc
      // (do "clush -a touch /tmp/drill/spin" to turn this on across all the cluster nodes, and to
      // release the spinning threads do "clush -a rm /tmp/drill/spin")
      // The processID of the spinning thread (along with the error message) should then be found
      // in a file like  /tmp/drill/spin4148663301172491613.tmp
      if (SPIN_FILE.exists()) {
        final File tmpDir = new File("/tmp/drill");
        File outErr = null;
        try {
          outErr = File.createTempFile("spin", ".tmp", tmpDir);
          final BufferedWriter bw = new BufferedWriter(new FileWriter(outErr));
          bw.write("Spinning process: " + ManagementFactory.getRuntimeMXBean().getName()
          /* After upgrading to JDK 9 - replace with: ProcessHandle.current().getPid() */);
          bw.write("\nError cause: " +
            (errorType == DrillPBError.ErrorType.SYSTEM ? ("SYSTEM ERROR: " + ErrorHelper.getRootMessage(cause)) : message));
          bw.close();
        } catch (final Exception ex) {
          logger.warn("Failed creating a spinner tmp message file: {}", ex);
        }
        while (SPIN_FILE.exists()) {
          try { sleep(1_000); } catch (final Exception ex) { /* ignore interruptions */ }
        }
        try { outErr.delete(); } catch (final Exception ex) { } // cleanup - remove err msg file
      }

      if (uex != null) {
        return uex;
      }

      final boolean isSystemError = errorType == DrillPBError.ErrorType.SYSTEM;

      // make sure system errors use the root error message and display the root cause class name
      if (isSystemError) {
        message = ErrorHelper.getRootMessage(cause);
      }

      final UserException newException = new UserException(this);

      // since we just created a new exception, we should log it for later reference. If this is a system error, this is
      // an issue that the Drill admin should pay attention to and we should log as ERROR. However, if this is a user
      // mistake or data read issue, the system admin should not be concerned about these and thus we'll log this
      // as an INFO message.
      if (isSystemError) {
        logger.error(newException.getMessage(), newException);
      } else {
        final StringBuilder buf = new StringBuilder();
        buf.append("User Error Occurred");
        if (message != null) {
          buf.append(": ").append(message);
        }
        if (cause != null) {
          buf.append(" (").append(cause.getMessage()).append(")");
        }
        logger.info(buf.toString(), newException);
      }

      return newException;
    }

    /**
     * Builds a user exception or returns the wrapped one.
     *
     * @return user exception
     * @deprecated Use {@link #build(Logger)} instead. If the error is a system error, the error message is logged to
     * this {@link UserException#logger}.
     */
    @Deprecated
    public UserException build() {
      return build(logger);
    }
  }

  private final DrillPBError.ErrorType errorType;

  private final UserExceptionContext context;

  protected UserException(final DrillPBError.ErrorType errorType, final String message, final Throwable cause) {
    super(message, cause);

    this.errorType = errorType;
    this.context = new UserExceptionContext();
  }

  private UserException(final Builder builder) {
    super(builder.message, builder.cause);
    this.errorType = builder.errorType;
    this.context = builder.context;
  }

  public Builder rebuild() {
    return new Builder(this);
  }

  /**
   * generates the message that will be displayed to the client without the stack trace.
   *
   * @return non verbose error message
   */
  @Override
  public String getMessage() {
    return generateMessage(true);
  }

  public String getMessage(boolean includeErrorIdAndIdentity) {
    return generateMessage(includeErrorIdAndIdentity);
  }

  /**
   *
   * @return the error message that was passed to the builder
   */
  public String getOriginalMessage() {
    return super.getMessage();
  }

  /**
   * generates the message that will be displayed to the client. The message also contains the stack trace.
   *
   * @return verbose error message
   */
  public String getVerboseMessage() {
    return getVerboseMessage(true);
  }

  public String getVerboseMessage(boolean includeErrorIdAndIdentity) {
    return generateMessage(includeErrorIdAndIdentity) + "\n\n" + ErrorHelper.buildCausesMessage(getCause());
  }

  /**
   * returns or creates a DrillPBError object corresponding to this user exception.
   *
   * @param verbose should the error object contain the verbose error message ?
   * @return protobuf error object
   */
  public DrillPBError getOrCreatePBError(final boolean verbose) {
    final String message = verbose ? getVerboseMessage() : getMessage();

    final DrillPBError.Builder builder = DrillPBError.newBuilder();
    builder.setErrorType(errorType);
    builder.setErrorId(context.getErrorId());
    if (context.getEndpoint() != null) {
      builder.setEndpoint(context.getEndpoint());
    }
    builder.setMessage(message);

    if (getCause() != null) {
      // some unit tests use this information to make sure a specific exception was thrown in the server
      builder.setException(ErrorHelper.getWrapper(getCause()));
    } else {
      // not a wrapper exception
      builder.setException(ErrorHelper.getWrapper(this));
    }
    return builder.build();
  }

  public String getErrorId() {
    return context.getErrorId();
  }

  public DrillPBError.ErrorType getErrorType() {
    return errorType;
  }

  public String getErrorLocation() {
    final DrillbitEndpoint ep = context.getEndpoint();
    if (ep != null) {
      return ep.getAddress() + ":" + ep.getUserPort();
    } else {
      return null;
    }
  }
  /**
   * Generates a user error message that has the following structure:
   * ERROR TYPE: ERROR_MESSAGE
   * CONTEXT
   * [ERROR_ID on DRILLBIT_IP:DRILLBIT_USER_PORT]
   *
   * @return generated user error message
   */
  private String generateMessage(boolean includeErrorIdAndIdentity) {
    final boolean seeLogsMessage = errorType == DrillPBError.ErrorType.INTERNAL_ERROR
        || errorType == DrillPBError.ErrorType.SYSTEM;
    return errorType + " ERROR: " + super.getMessage() + "\n\n" +
        context.generateContextMessage(includeErrorIdAndIdentity, seeLogsMessage);
  }

}
