// Copyright (c) 2017, 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.

import 'package:front_end/src/fasta/problems.dart';
import 'package:kernel/ast.dart';

/// Convert '→' to '->' because '→' doesn't show up in some terminals.
/// Remove prefixes that are used very often in tests.
String _shortenInstrumentationString(String s) => s
    .replaceAll('→', '->')
    .replaceAll('dart.core::', '')
    .replaceAll('dart.async::', '')
    .replaceAll('test::', '');

/// Interface providing the ability to record property/value pairs associated
/// with source file locations.  Intended to facilitate testing.
abstract class Instrumentation {
  /// Records a property/value pair associated with the given URI and offset.
  void record(Uri uri, int offset, String property, InstrumentationValue value);
}

/// Interface for values recorded by [Instrumentation].
abstract class InstrumentationValue {
  const InstrumentationValue();

  /// Checks if the given String is an accurate description of this value.
  ///
  /// The default implementation just checks for equality with the return value
  /// of [toString], however derived classes may want a more sophisticated
  /// implementation (e.g. to allow abbreviations in the description).
  ///
  /// Derived classes should ensure that the invariant holds:
  /// `this.matches(this.toString())` should always return `true`.
  bool matches(String description) => description == toString();
}

/// Instance of [InstrumentationValue] describing a forwarding stub.
class InstrumentationValueForForwardingStub extends InstrumentationValue {
  final Procedure procedure;

  InstrumentationValueForForwardingStub(this.procedure);

  @override
  String toString() {
    var buffer = new StringBuffer();
    void writeParameter(VariableDeclaration parameter) {
      var covariances = <String>[];
      if (parameter.isGenericCovariantInterface) {
        covariances.add('genericInterface');
      }
      if (parameter.isGenericCovariantImpl) {
        covariances.add('genericImpl');
      }
      if (parameter.isCovariant) {
        covariances.add('explicit');
      }
      buffer.write('covariance=(${covariances.join(', ')}) ');
      buffer.write(parameter.type);
      buffer.write(' ');
      buffer.write(parameter.name);
    }

    if (procedure.isAbstract) {
      buffer.write('abstract ');
    }
    var function = procedure.function;
    if (procedure.isGenericContravariant) {
      buffer.write('genericContravariant ');
    }
    buffer.write(function.returnType);
    buffer.write(' ');
    switch (procedure.kind) {
      case ProcedureKind.Operator:
        buffer.write('operator');
        break;
      case ProcedureKind.Method:
        break;
      case ProcedureKind.Setter:
        buffer.write('set ');
        break;
      case ProcedureKind.Getter:
        buffer.write('get ');
        break;
      default:
        unhandled('${procedure.kind}', 'InstrumentationValueForForwardingStub',
            -1, null);
        break;
    }
    buffer.write(procedure.name.name);
    if (function.typeParameters.isNotEmpty) {
      buffer.write('<');
      for (int i = 0; i < function.typeParameters.length; i++) {
        if (i != 0) buffer.write(', ');
        var typeParameter = function.typeParameters[i];
        var covariances = <String>[];
        if (typeParameter.isGenericCovariantInterface) {
          covariances.add('genericInterface');
        }
        if (typeParameter.isGenericCovariantImpl) {
          covariances.add('genericImpl');
        }
        buffer.write('covariance=(${covariances.join(', ')}) ');
        buffer.write(typeParameter.name);
        buffer.write(' extends ');
        buffer.write(
            new InstrumentationValueForType(typeParameter.bound).toString());
      }
      buffer.write('>');
    }
    buffer.write('(');
    for (int i = 0; i < function.positionalParameters.length; i++) {
      if (i != 0) buffer.write(', ');
      if (i == function.requiredParameterCount) buffer.write('[');
      writeParameter(function.positionalParameters[i]);
    }
    if (function.requiredParameterCount <
        function.positionalParameters.length) {
      buffer.write(']');
    }
    if (function.namedParameters.isNotEmpty) {
      if (function.positionalParameters.length != 0) buffer.write(', ');
      buffer.write('{');
      for (int i = 0; i < function.namedParameters.length; i++) {
        if (i != 0) buffer.write(', ');
        writeParameter(function.namedParameters[i]);
      }
      buffer.write('}');
    }
    buffer.write(')');
    return _shortenInstrumentationString(buffer.toString());
  }
}

/// Instance of [InstrumentationValue] describing a [Member].
class InstrumentationValueForMember extends InstrumentationValue {
  final Member member;

  InstrumentationValueForMember(this.member);

  @override
  String toString() => _shortenInstrumentationString(member.toString());
}

/// Instance of [InstrumentationValue] describing a [DartType].
class InstrumentationValueForType extends InstrumentationValue {
  final DartType type;

  InstrumentationValueForType(this.type);

  @override
  String toString() => _shortenInstrumentationString(type.toString());
}

/// Instance of [InstrumentationValue] describing a list of [DartType]s.
class InstrumentationValueForTypeArgs extends InstrumentationValue {
  final List<DartType> types;

  InstrumentationValueForTypeArgs(this.types);

  @override
  String toString() => types
      .map((type) => new InstrumentationValueForType(type).toString())
      .join(', ');
}

/// Instance of [InstrumentationValue] which only matches the given literal
/// string.
class InstrumentationValueLiteral extends InstrumentationValue {
  final String value;

  const InstrumentationValueLiteral(this.value);

  @override
  String toString() => value;
}
