// Copyright (c) 2021, 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 'dart:convert';

import "package:expect/expect.dart";

/// Helper class for determining when no argument is passed to a function.
class Absent {
  const Absent();
}

const absent = Absent();

/// Returns an approximate representation of the syntax that was used to
/// construct [x].  Extra parentheses are used around unary and binary
/// expressions to disambiguate precedence.
String syntax(Object x) {
  var knownSyntax = SyntaxTracker.known[x];
  if (knownSyntax != null) return knownSyntax;
  if (x is SyntaxTracker || x is num) {
    return x.toString();
  } else if (x is List) {
    return '[${x.map(syntax).join(', ')}]';
  } else if (x is Set) {
    if (x.isEmpty) return 'Set()';
    return '{${x.map(syntax).join(', ')}}';
  } else if (x is Map) {
    if (x.isEmpty) return '{}';
    var entries = x.entries
        .map((entry) => '${syntax(entry.key)}: ${syntax(entry.value)}');
    return '{ ${entries.join(', ')} }';
  } else if (x is String) {
    return json.encode(x);
  } else {
    throw UnimplementedError('Unknown syntax for $x.  '
        'Consider adding to `SyntaxTracker.known`.');
  }
}

/// Instances of this class record the syntax of operations performed on them.
class SyntaxTracker {
  final String _syntax;

  SyntaxTracker(this._syntax);

  String toString() => _syntax;

  static String args([Object x = absent, Object y = absent]) =>
      '(${[x, y].where((v) => v is! Absent).join(', ')})';

  static String typeArgs(Type T, Type U) =>
      T == dynamic && U == dynamic ? '' : '<${syntax(T)}, ${syntax(U)}>';

  /// Simple objects with known syntactic representations.  Tests can add to
  /// this map.
  static Map<Object, String> known = {
    true: 'true',
    false: 'false',
    null: 'null'
  };
}

/// Extension allowing us to detect the syntax of most operations performed on
/// arbitrary types.
extension SyntaxTrackingExtension on Object {
  Object method<T, U>([Object x = absent, Object y = absent]) => SyntaxTracker(
      '${syntax(this)}.method${SyntaxTracker.typeArgs(T, U)}${SyntaxTracker.args(x, y)}');

  Object call<T, U>([Object x = absent, Object y = absent]) => SyntaxTracker(
      '${syntax(this)}${SyntaxTracker.typeArgs(T, U)}${SyntaxTracker.args(x, y)}');

  Object get getter => SyntaxTracker('${syntax(this)}.getter');

  Object operator [](Object index) =>
      SyntaxTracker('${syntax(this)}[${syntax(index)}]');

  Object operator -() => SyntaxTracker('(-${syntax(this)})');

  Object operator ~() => SyntaxTracker('(~${syntax(this)})');

  Object operator *(Object other) =>
      SyntaxTracker('(${syntax(this)} * ${syntax(other)})');

  Object operator /(Object other) =>
      SyntaxTracker('(${syntax(this)} / ${syntax(other)})');

  Object operator ~/(Object other) =>
      SyntaxTracker('(${syntax(this)} ~/ ${syntax(other)})');

  Object operator %(Object other) =>
      SyntaxTracker('(${syntax(this)} % ${syntax(other)})');

  Object operator +(Object other) =>
      SyntaxTracker('(${syntax(this)} + ${syntax(other)})');

  Object operator -(Object other) =>
      SyntaxTracker('(${syntax(this)} - ${syntax(other)})');

  Object operator <<(Object other) =>
      SyntaxTracker('(${syntax(this)} << ${syntax(other)})');

  Object operator >>(Object other) =>
      SyntaxTracker('(${syntax(this)} >> ${syntax(other)})');

  Object operator &(Object other) =>
      SyntaxTracker('(${syntax(this)} & ${syntax(other)})');

  Object operator ^(Object other) =>
      SyntaxTracker('(${syntax(this)} ^ ${syntax(other)})');

  Object operator |(Object other) =>
      SyntaxTracker('(${syntax(this)} | ${syntax(other)})');

  Object operator <(Object other) =>
      SyntaxTracker('(${syntax(this)} < ${syntax(other)})');

  Object operator >(Object other) =>
      SyntaxTracker('(${syntax(this)} > ${syntax(other)})');

  Object operator <=(Object other) =>
      SyntaxTracker('(${syntax(this)} <= ${syntax(other)})');

  Object operator >=(Object other) =>
      SyntaxTracker('(${syntax(this)} >= ${syntax(other)})');
}

void checkSyntax(Object x, String expectedSyntax) {
  Expect.equals(expectedSyntax, syntax(x));
}

Object f<T, U>([Object x = absent, Object y = absent]) => SyntaxTracker(
    'f${SyntaxTracker.typeArgs(T, U)}${SyntaxTracker.args(x, y)}');

Object x = SyntaxTracker('x');
