// Copyright (c) 2013, 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.

library barback.errors;

import 'package:stack_trace/stack_trace.dart';

import 'asset_id.dart';
import 'transformer.dart';
import 'utils.dart';

/// Error thrown when an asset with [id] cannot be found.
class AssetNotFoundException implements Exception {
  final AssetId id;

  AssetNotFoundException(this.id);

  String toString() => "Could not find asset $id.";
}

/// Replaces any occurrences of [AggregateException] in [errors] with the list
/// of errors it contains.
Iterable<BarbackException> flattenAggregateExceptions(
    Iterable<BarbackException> errors) {
  return errors.expand((error) {
    if (error is! AggregateException) return [error];
    return error.errors;
  });
}

/// The interface for exceptions from the barback graph or its transformers.
///
/// These exceptions are never produced by programming errors in barback.
abstract class BarbackException implements Exception {
  /// Takes a collection of [BarbackExceptions] and returns a single exception
  /// that contains them all.
  ///
  /// If [errors] is empty, returns `null`. If it only has one error, that
  /// error is returned. Otherwise, an [AggregateException] is returned.
  static BarbackException aggregate(Iterable<BarbackException> errors) {
    if (errors.isEmpty) return null;
    if (errors.length == 1) return errors.single;
    return new AggregateException(errors);
  }
}

/// An error that wraps a collection of other [BarbackException]s.
///
/// It implicitly flattens any [AggregateException]s that occur in the list of
/// exceptions it wraps.
class AggregateException implements BarbackException {
  final Set<BarbackException> errors;

  AggregateException(Iterable<BarbackException> errors)
      : errors = flattenAggregateExceptions(errors).toSet();

  String toString() {
    var buffer = new StringBuffer();
    buffer.writeln("Multiple errors occurred:\n");

    for (var error in errors) {
      buffer.writeln(prefixLines(error.toString(),
                                 prefix: "  ", firstPrefix: "- "));
    }

    return buffer.toString();
  }
}

/// Error thrown when two or more transformers both output an asset with [id].
class AssetCollisionException implements BarbackException {
  /// All the transforms that output an asset with [id].
  ///
  /// If this only contains a single transform, that indicates that a
  /// transformer produced an output that collides with a source asset or an
  /// asset from a previous phase.
  final Set<TransformInfo> transforms;
  final AssetId id;

  AssetCollisionException(Iterable<TransformInfo> transforms, this.id)
      : transforms = new Set.from(transforms);

  String toString() => "Transforms $transforms all emitted asset $id.";
}

/// Error thrown when a transformer requests an input [id] which cannot be
/// found.
class MissingInputException implements BarbackException {
  /// The transform that requested [id].
  final TransformInfo transform;
  final AssetId id;

  MissingInputException(this.transform, this.id);

  String toString() => "Transform $transform tried to load missing input $id.";
}

/// Error thrown when a transformer outputs an asset to a different package than
/// the primary input's.
class InvalidOutputException implements BarbackException {
  /// The transform that output the asset.
  final TransformInfo transform;
  final AssetId id;

  InvalidOutputException(this.transform, this.id);

  String toString() => "Transform $transform emitted $id, which wasn't in the "
      "same package (${transform.primaryId.package}).";
}

/// Base class for an error that wraps another.
abstract class _WrappedException implements BarbackException {
  /// The wrapped exception.
  final error;
  final Chain stackTrace;

  _WrappedException(this.error, StackTrace stackTrace)
      : this.stackTrace = stackTrace == null ? null :
            new Chain.forTrace(stackTrace);

  String get _message;

  String toString() {
    var result = "$_message: $error";

    var stack = stackTrace;
    if (stack == null && error is Error) stack = error.stackTrace;
    if (stack != null) {
      result = "$result\n${stackTrace.terse}";
    }

    return result;
  }
}

/// Error wrapping an exception thrown by a transform.
class TransformerException extends _WrappedException {
  /// The transform that threw the exception.
  final TransformInfo transform;

  TransformerException(this.transform, error, StackTrace stackTrace)
      : super(error, stackTrace);

  String get _message => "Transform $transform threw error";
}

/// Error thrown when a source asset [id] fails to load.
///
/// This can be thrown either because the source asset was expected to exist and
/// did not or because reading it failed somehow.
class AssetLoadException extends _WrappedException {
  final AssetId id;

  AssetLoadException(this.id, error, [StackTrace stackTrace])
      : super(error, stackTrace);

  String get _message => "Failed to load source asset $id";
}

/// Information about a single transform in the barback graph.
///
/// Identifies a single transformation in the barback graph.
///
/// A transformation is uniquely identified by the ID of its primary input, and
/// the transformer that is applied to it.
class TransformInfo {
  /// The transformer that's run for this transform.
  final Transformer transformer;

  /// The id of this transform's primary asset.
  final AssetId primaryId;

  TransformInfo(this.transformer, this.primaryId);

  bool operator==(other) =>
      other is TransformInfo &&
      other.transformer == transformer &&
      other.primaryId == primaryId;

  int get hashCode => transformer.hashCode ^ primaryId.hashCode;

  String toString() => "$transformer on $primaryId";
}
