// 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:analyzer/dart/constant/value.dart';
import 'package:analyzer/dart/element/element.dart';
// ignore: implementation_imports
import 'package:analyzer/src/dart/constant/value.dart';

import '../utils.dart';

/// Attempts to extract what source code could be used to represent [object].
///
/// Returns `null` if it wasn't possible to parse [object], or [object] is a
/// primitive value (such as a number, string, boolean) that does not need to be
/// revived in order to represent it.
///
/// **NOTE**: Some returned [Revivable] instances are not representable as valid
/// Dart source code (such as referencing private constructors). It is up to the
/// build tool(s) using this library to surface error messages to the user.
Revivable reviveInstance(DartObject object, [LibraryElement origin]) {
  origin ??= object.type.element.library;
  final element = object.type.element;
  var url = Uri.parse(urlOfElement(element));
  if (element is FunctionElement) {
    return Revivable._(
      source: url.removeFragment(),
      accessor: element.name,
    );
  }
  if (element is MethodElement && element.isStatic) {
    return Revivable._(
      source: url.removeFragment(),
      accessor: '${element.enclosingElement.name}.${element.name}',
    );
  }
  // Enums are not included in .definingCompilationUnit.types.
  final clazz = element as ClassElement;
  if (clazz.isEnum) {
    for (final e in clazz.fields.where(
        (f) => f.isPublic && f.isConst && f.computeConstantValue() == object)) {
      return Revivable._(
        source: url.removeFragment(),
        accessor: '${clazz.name}.${e.name}',
      );
    }
  }

  // We try and return a public accessor/constructor if available.
  final allResults = <Revivable>[];

  /// Returns whether [result] is an acceptable result to immediately return.
  bool tryResult(Revivable result) {
    allResults.add(result);
    return !result.isPrivate;
  }

  for (final e in origin.definingCompilationUnit.types
      .expand((t) => t.fields)
      .where((f) => f.isConst && f.computeConstantValue() == object)) {
    final result = Revivable._(
      source: url.removeFragment(),
      accessor: '${clazz.name}.${e.name}',
    );
    if (tryResult(result)) {
      return result;
    }
  }
  final i = (object as DartObjectImpl).getInvocation();
  if (i != null) {
    url = Uri.parse(urlOfElement(i.constructor.enclosingElement));
    final result = Revivable._(
      source: url,
      accessor: i.constructor.name,
      namedArguments: i.namedArguments,
      positionalArguments: i.positionalArguments,
    );
    if (tryResult(result)) {
      return result;
    }
  }
  if (origin != null) {
    for (final e in origin.definingCompilationUnit.topLevelVariables.where(
      (f) => f.isConst && f.computeConstantValue() == object,
    )) {
      final result = Revivable._(
        source: Uri.parse(urlOfElement(origin)).replace(fragment: ''),
        accessor: e.name,
      );
      if (tryResult(result)) {
        return result;
      }
    }
  }
  // We could try and return the "best" result more intelligently.
  return allResults.first;
}

/// Decoded "instructions" for re-creating a const [DartObject] at runtime.
class Revivable {
  /// A URL pointing to the location and class name.
  ///
  /// For example, `LinkedHashMap` looks like: `dart:collection#LinkedHashMap`.
  ///
  /// An accessor to a top-level field or method does not have a fragment and
  /// is instead represented as just something like `dart:collection`, with the
  /// [accessor] field as the name of the symbol.
  final Uri source;

  /// Constructor or getter name used to invoke `const Class(...)`.
  ///
  /// Optional - if empty string (`''`) then this means the default constructor.
  final String accessor;

  /// Positional arguments used to invoke the constructor.
  final List<DartObject> positionalArguments;

  /// Named arguments used to invoke the constructor.
  final Map<String, DartObject> namedArguments;

  const Revivable._({
    this.source,
    this.accessor = '',
    this.positionalArguments = const [],
    this.namedArguments = const {},
  });

  /// Whether this instance is visible outside the same library.
  ///
  /// Builds tools may use this to fail when the symbol is expected to be
  /// importable (i.e. isn't used with `part of`).
  bool get isPrivate {
    return source.fragment.startsWith('_') || accessor.startsWith('_');
  }

  @override
  String toString() {
    if (source.fragment.isNotEmpty) {
      if (accessor.isEmpty) {
        return 'const $source';
      }
      return 'const $source.$accessor';
    }
    return '$source::$accessor';
  }
}
