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

library dart2js.code_output;

import 'dart:async';

import 'source_information.dart';

class CodeOutputMarker {
  final int offsetDelta;
  final SourceFileLocation sourcePosition;

  CodeOutputMarker(this.offsetDelta, this.sourcePosition);
}

abstract class CodeOutputListener {
  void onText(String text);
  void onDone(int length);
}

abstract class CodeOutput {
  /// Write [text] to this output.
  ///
  /// If the output is closed, a [StateError] is thrown.
  void add(String text);

  /// Adds the content of [buffer] to the output and adds its markers to
  /// [markers].
  ///
  /// If the output is closed, a [StateError] is thrown.
  void addBuffer(CodeBuffer buffer);

  /// Returns the number of characters currently write to this output.
  int get length;

  /// Returns `true` if this output has been closed.
  bool get isClosed;

  /// Closes the output. Further writes will cause a [StateError].
  void close();

  /// Applies [f] to every marker in this output.
  void forEachSourceLocation(void f(int targetOffset,
                                    SourceFileLocation sourceLocation));
}

abstract class AbstractCodeOutput extends CodeOutput {
  List<CodeOutputMarker> markers = new List<CodeOutputMarker>();
  int lastBufferOffset = 0;
  int mappedRangeCounter = 0;
  bool isClosed = false;

  void _addInternal(String text);

  @override
  void add(String text) {
    if (isClosed) {
      throw new StateError("Code output is closed. Trying to write '$text'.");
    }
    if (mappedRangeCounter == 0) setSourceLocation(null);
    _addInternal(text);
  }

  @override
  void addBuffer(CodeBuffer other) {
    if (other.markers.length > 0) {
      CodeOutputMarker firstMarker = other.markers[0];
      int offsetDelta =
          length + firstMarker.offsetDelta - lastBufferOffset;
      markers.add(new CodeOutputMarker(offsetDelta,
                                       firstMarker.sourcePosition));
      for (int i = 1; i < other.markers.length; ++i) {
        markers.add(other.markers[i]);
      }
      lastBufferOffset = length + other.lastBufferOffset;
    }
    if (!other.isClosed) {
      other.close();
    }
    _addInternal(other.getText());
  }

  void beginMappedRange() {
    ++mappedRangeCounter;
  }

  void endMappedRange() {
    assert(mappedRangeCounter > 0);
    --mappedRangeCounter;
  }

  void setSourceLocation(SourceFileLocation sourcePosition) {
    if (sourcePosition == null) {
      if (markers.length > 0 && markers.last.sourcePosition == null) return;
    }
    int offsetDelta = length - lastBufferOffset;
    markers.add(new CodeOutputMarker(offsetDelta, sourcePosition));
    lastBufferOffset = length;
  }

  void forEachSourceLocation(void f(int targetOffset, var sourcePosition)) {
    int targetOffset = 0;
    markers.forEach((marker) {
      targetOffset += marker.offsetDelta;
      f(targetOffset, marker.sourcePosition);
    });
  }

  void close() {
    if (isClosed) {
      throw new StateError("Code output is already closed.");
    }
    isClosed = true;
  }
}

/// [CodeOutput] using a [StringBuffer] as backend.
class CodeBuffer extends AbstractCodeOutput {
  StringBuffer buffer = new StringBuffer();

  @override
  void _addInternal(String text) {
    buffer.write(text);
  }

  @override
  int get length => buffer.length;

  String getText() {
    return buffer.toString();
  }

  String toString() {
    throw "Don't use CodeBuffer.toString() since it drops sourcemap data.";
  }
}

/// [CodeOutput] using a [CompilationOutput] as backend.
class StreamCodeOutput extends AbstractCodeOutput {
  int length = 0;
  final EventSink<String> output;
  final List<CodeOutputListener> _listeners;

  StreamCodeOutput(this.output, [this._listeners]);

  @override
  void _addInternal(String text) {
    output.add(text);
    length += text.length;
    if (_listeners != null) {
      _listeners.forEach((listener) => listener.onText(text));
    }
  }

  void close() {
    output.close();
    super.close();
    if (_listeners != null) {
      _listeners.forEach((listener) => listener.onDone(length));
    }
  }
}
