// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

part of dart.core;

// Exceptions are thrown either by the VM or from Dart code.

/**
 * A marker interface implemented by all core library exceptions.
 *
 * An [Exception] is intended to convey information to the user about a failure,
 * so that the error can be addressed programmatically. It is intended to be
 * caught, and it should contain useful data fields.
 *
 * Creating instances of [Exception] directly with `Exception("message")`
 * is discouraged in library code since it doesn't give users a precise
 * type they can catch. It may be reasonable to use instances of this
 * class in tests or during development.
 */
abstract class Exception {
  factory Exception([var message]) => _Exception(message);
}

/** Default implementation of [Exception] which carries a message. */
class _Exception implements Exception {
  final message;

  _Exception([this.message]);

  String toString() {
    if (message == null) return "Exception";
    return "Exception: $message";
  }
}

/**
 * Exception thrown when a string or some other data does not have an expected
 * format and cannot be parsed or processed.
 */
class FormatException implements Exception {
  /**
   * A message describing the format error.
   */
  final String message;

  /**
   * The actual source input which caused the error.
   *
   * This is usually a [String], but can be other types too.
   * If it is a string, parts of it may be included in the [toString] message.
   *
   * The source is `null` if omitted or unknown.
   */
  final source;

  /**
   * The offset in [source] where the error was detected.
   *
   * A zero-based offset into the source that marks the format error causing
   * this exception to be created. If `source` is a string, this should be a
   * string index in the range `0 <= offset <= source.length`.
   *
   * If input is a string, the [toString] method may represent this offset as
   * a line and character position. The offset should be inside the string,
   * or at the end of the string.
   *
   * May be omitted. If present, [source] should also be present if possible.
   */
  final int offset;

  /**
   * Creates a new FormatException with an optional error [message].
   *
   * Optionally also supply the actual [source] with the incorrect format,
   * and the [offset] in the format where a problem was detected.
   */
  @pragma("vm:entry-point")
  const FormatException([this.message = "", this.source, this.offset]);

  /**
   * Returns a description of the format exception.
   *
   * The description always contains the [message].
   *
   * If [source] is present and is a string, the description will contain
   * (at least a part of) the source.
   * If [offset] is also provided, the part of the source included will
   * contain that offset, and the offset will be marked.
   *
   * If the source is a string and it contains a line break before offset,
   * only the line containing offset will be included, and its line number
   * will also be part of the description. Line and character offsets are
   * 1-based.
   */
  String toString() {
    String report = "FormatException";
    if (message != null && "" != message) {
      report = "$report: $message";
    }
    int offset = this.offset;
    Object objectSource = this.source;
    if (objectSource is String) {
      String source = objectSource;
      if (offset != null && (offset < 0 || offset > source.length)) {
        offset = null;
      }
      // Source is string and offset is null or valid.
      if (offset == null) {
        if (source.length > 78) {
          source = source.substring(0, 75) + "...";
        }
        return "$report\n$source";
      }
      int lineNum = 1;
      int lineStart = 0;
      bool previousCharWasCR = false;
      for (int i = 0; i < offset; i++) {
        int char = source.codeUnitAt(i);
        if (char == 0x0a) {
          if (lineStart != i || !previousCharWasCR) {
            lineNum++;
          }
          lineStart = i + 1;
          previousCharWasCR = false;
        } else if (char == 0x0d) {
          lineNum++;
          lineStart = i + 1;
          previousCharWasCR = true;
        }
      }
      if (lineNum > 1) {
        report += " (at line $lineNum, character ${offset - lineStart + 1})\n";
      } else {
        report += " (at character ${offset + 1})\n";
      }
      int lineEnd = source.length;
      for (int i = offset; i < source.length; i++) {
        int char = source.codeUnitAt(i);
        if (char == 0x0a || char == 0x0d) {
          lineEnd = i;
          break;
        }
      }
      int length = lineEnd - lineStart;
      int start = lineStart;
      int end = lineEnd;
      String prefix = "";
      String postfix = "";
      if (length > 78) {
        // Can't show entire line. Try to anchor at the nearest end, if
        // one is within reach.
        int index = offset - lineStart;
        if (index < 75) {
          end = start + 75;
          postfix = "...";
        } else if (end - offset < 75) {
          start = end - 75;
          prefix = "...";
        } else {
          // Neither end is near, just pick an area around the offset.
          start = offset - 36;
          end = offset + 36;
          prefix = postfix = "...";
        }
      }
      String slice = source.substring(start, end);
      int markOffset = offset - start + prefix.length;
      return "$report$prefix$slice$postfix\n${" " * markOffset}^\n";
    } else {
      // The source is not a string.
      if (offset != null) {
        report += " (at offset $offset)";
      }
      return report;
    }
  }
}

// Exception thrown when doing integer division with a zero divisor.
class IntegerDivisionByZeroException implements Exception {
  @pragma("vm:entry-point")
  const IntegerDivisionByZeroException();
  String toString() => "IntegerDivisionByZeroException";
}
