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

import 'dart:async';
import 'dart:collection';

import 'asset_cascade.dart';
import 'asset_forwarder.dart';
import 'asset_node.dart';
import 'errors.dart';
import 'phase.dart';
import 'utils.dart';

/// A class that handles a single output of a phase.
///
/// Normally there's only a single [AssetNode] for a phase's output, but it's
/// possible that multiple transformers in the same phase emit assets with the
/// same id, causing collisions. This handles those collisions by forwarding the
/// chronologically first asset.
///
/// When the asset being forwarding changes, the old value of [output] will be
/// marked as removed and a new value will replace it. Users of this class can
/// be notified of this using [onAsset].
class PhaseOutput {
  /// The phase for which this is an output.
  final Phase _phase;

  /// The asset node for this output.
  AssetNode get output => _outputForwarder.node;
  AssetForwarder _outputForwarder;

  /// A stream that emits an [AssetNode] each time this output starts forwarding
  /// a new asset.
  Stream<AssetNode> get onAsset => _onAssetController.stream;
  final _onAssetController = new StreamController<AssetNode>();

  /// The assets for this output.
  ///
  /// If there's no collision, this will only have one element. Otherwise, it
  /// will be ordered by which asset was added first.
  final _assets = new Queue<AssetNode>();

  /// The [AssetCollisionException] for this output, or null if there is no
  /// collision currently.
  AssetCollisionException get collisionException {
    if (_assets.length == 1) return null;
    return new AssetCollisionException(
        _assets.where((asset) => asset.transform != null)
            .map((asset) => asset.transform.info),
        output.id);
  }

  PhaseOutput(this._phase, AssetNode output)
      : _outputForwarder = new AssetForwarder(output) {
    assert(!output.state.isRemoved);
    add(output);
  }

  /// Adds an asset node as an output with this id.
  void add(AssetNode node) {
    assert(node.id == output.id);
    assert(!output.state.isRemoved);
    _assets.add(node);
    _watchAsset(node);
  }

  /// Removes all existing listeners on [output] without actually closing
  /// [this].
  ///
  /// This marks [output] as removed, but immediately replaces it with a new
  /// [AssetNode] in the same state as the old output. This is used when adding
  /// a new [Phase] to cause consumers of the prior phase's outputs to be to
  /// start consuming the new phase's outputs instead.
  void removeListeners() {
    _outputForwarder.close();
    _outputForwarder = new AssetForwarder(_assets.first);
    _onAssetController.add(output);
  }

  /// Watches [node] to adjust [_assets] and [output] when it's removed.
  void _watchAsset(AssetNode node) {
    node.whenRemoved(() {
      if (_assets.length == 1) {
        assert(_assets.single == node);
        _outputForwarder.close();
        _onAssetController.close();
        return;
      }

      // If there was more than one asset, we're resolving a collision --
      // possibly partially.
      var wasFirst = _assets.first == node;
      _assets.remove(node);

      // If this was the first asset, we replace it with the next asset
      // (chronologically).
      if (wasFirst) removeListeners();

      // If there's still a collision, report it. This lets the user know if
      // they've successfully resolved the collision or not.
      if (_assets.length > 1) {
        // Pump the event queue to ensure that the removal of the input triggers
        // a new build to which we can attach the error.
        // TODO(nweiz): report this through the output asset.
        newFuture(() => _phase.cascade.reportError(collisionException));
      }
    });
  }
}
