// 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.barback;

import 'dart:async';

import 'asset/asset.dart';
import 'asset/asset_id.dart';
import 'asset/asset_set.dart';
import 'log.dart';
import 'build_result.dart';
import 'errors.dart';
import 'graph/package_graph.dart';
import 'package_provider.dart';
import 'transformer/transformer.dart';

/// A general-purpose asynchronous build dependency graph manager.
///
/// It consumes source assets (including Dart files) in a set of packages,
/// runs transformations on them, and then tracks which sources have been
/// modified and which transformations need to be re-run.
///
/// To do this, you give barback a [PackageProvider] which can yield a set of
/// [Transformer]s and raw source [Asset]s. Then you tell it which input files
/// have been added or modified by calling [updateSources]. Barback will
/// automatically wire up the appropriate transformers to those inputs and
/// start running them asynchronously. If a transformer produces outputs that
/// can be consumed by other transformers, they will automatically be pipelined
/// correctly.
///
/// You can then request assets (either source or generated) by calling
/// [getAssetById]. This will wait for any necessary transformations and then
/// return the asset.
///
/// When source files have been modified or removed, tell barback by calling
/// [updateSources] and [removeSources] as appropriate. Barback will
/// automatically track which transformations are affected by those changes and
/// re-run them as needed.
///
/// Barback tries to be resilient to errors since assets are often in an
/// in-progress state. When errors occur, they will be captured and emitted on
/// the [errors] stream.
class Barback {
  /// The graph managed by this instance.
  final PackageGraph _graph;

  /// A stream that emits a [BuildResult] each time the build is completed,
  /// whether or not it succeeded.
  ///
  /// This will emit a result only once every package's [AssetCascade] has
  /// finished building.
  ///
  /// If an unexpected error in barback itself occurs, it will be emitted
  /// through this stream's error channel.
  Stream<BuildResult> get results => _graph.results;

  /// A stream that emits any errors from the graph or the transformers.
  ///
  /// This emits errors as they're detected. If an error occurs in one part of
  /// the graph, unrelated parts will continue building.
  ///
  /// This will not emit programming errors from barback itself. Those will be
  /// emitted through the [results] stream's error channel.
  Stream get errors => _graph.errors;

  /// The stream of [LogEntry] objects used to report transformer log entries.
  ///
  /// If this stream has listeners, then log entries will go to that.
  /// Otherwise, a default logger will display them.
  Stream<LogEntry> get log => _graph.log;

  Barback(PackageProvider provider)
      : _graph = new PackageGraph(provider);

  /// Gets the asset identified by [id].
  ///
  /// If [id] is for a generated or transformed asset, this will wait until
  /// it has been created and return it. If the asset cannot be found, throws
  /// [AssetNotFoundException].
  Future<Asset> getAssetById(AssetId id) {
    return _graph.getAssetNode(id).then((node) {
      if (node == null) throw new AssetNotFoundException(id);
      return node.asset;
    });
  }

  /// Adds [sources] to the graph's known set of source assets.
  ///
  /// Begins applying any transforms that can consume any of the sources. If a
  /// given source is already known, it is considered modified and all
  /// transforms that use it will be re-applied.
  void updateSources(Iterable<AssetId> sources) =>
      _graph.updateSources(sources);

  /// Removes [removed] from the graph's known set of source assets.
  void removeSources(Iterable<AssetId> removed) =>
      _graph.removeSources(removed);

  /// Gets all output assets.
  ///
  /// If a build is currently in progress, waits until it completes. The
  /// returned future will complete with a [BarbackException] if the build is
  /// not successful.
  Future<AssetSet> getAllAssets() => _graph.getAllAssets();

  /// Sets the transformer phases for [package]'s assets to [transformers].
  ///
  /// To the extent that [transformers] is similar to the previous transformer
  /// phases for [package], the existing asset graph will be preserved.
  ///
  /// Elements of the inner iterable of [transformers] must be [Transformer]s,
  /// [TransformerGroup]s, or [AggregateTransformer]s.
  void updateTransformers(String package, Iterable<Iterable> transformers) =>
      _graph.updateTransformers(package, transformers);
}
