// 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_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.
class PhaseOutput {
  /// The phase for which this is an output.
  final Phase _phase;

  /// The asset node for this output.
  AssetNode get output => _outputController.node;
  AssetNodeController _outputController;

  /// 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)
      : _outputController = new AssetNodeController.from(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);
    _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() {
    _outputController.setRemoved();
    _outputController = new AssetNodeController.from(_assets.first);
  }

  /// Watches [node] for state changes and adjusts [_assets] and [output]
  /// appropriately when they occur.
  void _watchAsset(AssetNode node) {
    node.onStateChange.listen((state) {
      if (state.isRemoved) {
        _removeAsset(node);
        return;
      }
      if (_assets.first != node) return;

      if (state.isAvailable) {
        _outputController.setAvailable(node.asset);
      } else {
        assert(state.isDirty);
        _outputController.setDirty();
      }
    });
  }

  /// Removes [node] as an output.
  void _removeAsset(AssetNode node) {
    if (_assets.length == 1) {
      assert(_assets.single == node);
      _outputController.setRemoved();
      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) {
      var newOutput = _assets.first;
      _outputController.setTransform(newOutput.transform);
      if (newOutput.state.isAvailable) {
        if (output.state.isAvailable) _outputController.setDirty();
        _outputController.setAvailable(newOutput.asset);
      } else {
        assert(newOutput.isDirty);
        if (!output.state.isDirty) _outputController.setDirty();
      }
    }

    // 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));
    }
  }
}
