// Copyright (c) 2015, 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.source_information;

import '../dart2jslib.dart' show SourceSpan;
import '../elements/elements.dart' show AstElement;
import '../scanner/scannerlib.dart' show Token;
import '../tree/tree.dart' show Node;
import 'code_output.dart';
import 'source_file.dart';

/// Interface for passing source information, for instance for use in source
/// maps, through the backend.
abstract class SourceInformation {
  SourceSpan get sourceSpan;
  void beginMapping(CodeOutput output);
  void endMapping(CodeOutput output);
}

/// Source information that contains start source position and optionally an
/// end source position.
class StartEndSourceInformation implements SourceInformation {
  final SourceFileLocation startPosition;
  final SourceFileLocation endPosition;

  StartEndSourceInformation(this.startPosition, [this.endPosition]);

  SourceSpan get sourceSpan {
    Uri uri = Uri.parse(startPosition.sourceFile.filename);
    int begin = startPosition.offset;
    int end = endPosition == null ? begin : endPosition.offset;
    return new SourceSpan(uri, begin, end);
  }

  void beginMapping(CodeBuffer output) {
    output.beginMappedRange();
    output.setSourceLocation(startPosition);
  }

  void endMapping(CodeBuffer output) {
    if (endPosition != null) {
      output.setSourceLocation(endPosition);
    }
    output.endMappedRange();
  }

  int get hashCode {
    return (startPosition.hashCode * 17 +
            endPosition.hashCode * 19)
           & 0x7FFFFFFF;
  }

  bool operator ==(other) {
    if (identical(this, other)) return true;
    if (other is! StartEndSourceInformation) return false;
    return startPosition == other.startPosition &&
           endPosition == other.endPosition;
  }

  // TODO(johnniwinther): Remove this method. Source information should be
  // computed based on the element by provided from statements and expressions.
  static StartEndSourceInformation computeSourceInformation(
      AstElement element) {

    AstElement implementation = element.implementation;
    SourceFile sourceFile = implementation.compilationUnit.script.file;
    String name = element.name;
    Node node = implementation.node;
    Token beginToken;
    Token endToken;
    if (node == null) {
      // Synthesized node. Use the enclosing element for the location.
      beginToken = endToken = element.position;
    } else {
      beginToken = node.getBeginToken();
      endToken = node.getEndToken();
    }
    // TODO(podivilov): find the right sourceFile here and remove offset
    // checks below.
    SourceFileLocation sourcePosition, endSourcePosition;
    if (beginToken.charOffset < sourceFile.length) {
      sourcePosition =
          new TokenSourceFileLocation(sourceFile, beginToken, name);
    }
    if (endToken.charOffset < sourceFile.length) {
      endSourcePosition =
          new TokenSourceFileLocation(sourceFile, endToken, name);
    }
    return new StartEndSourceInformation(sourcePosition, endSourcePosition);
  }

  String toString() {
    StringBuffer sb = new StringBuffer();
    sb.write('${startPosition.getSourceUrl()}:');
    sb.write('[${startPosition.getLine()},${startPosition.getColumn()}]');
    if (endPosition != null) {
      sb.write('-[${endPosition.getLine()},${endPosition.getColumn()}]');
    }
    return sb.toString();
  }
}

// TODO(johnniwinther): Refactor this class to use getters.
abstract class SourceFileLocation {
  SourceFile sourceFile;

  SourceFileLocation(this.sourceFile) {
    assert(isValid());
  }

  int line;

  int get offset;

  String getSourceUrl() => sourceFile.filename;

  int getLine() {
    if (line == null) line = sourceFile.getLine(offset);
    return line;
  }

  int getColumn() => sourceFile.getColumn(getLine(), offset);

  String getSourceName();

  bool isValid() => offset < sourceFile.length;

  int get hashCode {
    return getSourceUrl().hashCode * 17 +
           offset.hashCode * 17 +
           getSourceName().hashCode * 23;
  }

  bool operator ==(other) {
    if (identical(this, other)) return true;
    if (other is! SourceFileLocation) return false;
    return getSourceUrl() == other.getSourceUrl() &&
           offset == other.offset &&
           getSourceName() == other.getSourceName();
  }

  String toString() => '${getSourceUrl()}:[${getLine()},${getColumn()}]';
}

class TokenSourceFileLocation extends SourceFileLocation {
  final Token token;
  final String name;

  TokenSourceFileLocation(SourceFile sourceFile, this.token, this.name)
    : super(sourceFile);

  int get offset => token.charOffset;

  String getSourceName() {
    return name;
  }

  String toString() {
    return '${super.toString()}:$name';
  }
}
