// 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 dynamic message;

  _Exception([this.message]);

  String toString() {
    Object? message = this.message;
    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 dynamic 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";
    Object? message = this.message;
    if (message != null && "" != message) {
      report = "$report: $message";
    }
    int? offset = this.offset;
    Object? source = this.source;
    if (source is String) {
      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";
}
