// 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';
import 'package:analyzer/dart/element/type.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]) {
  final objectType = object.type;
  Element? element = objectType!.alias?.element;
  if (element == null) {
    if (objectType is InterfaceType) {
      element = objectType.element;
    } else {
      element = object.toFunctionValue();
    }
  }
  origin ??= element!.library;
  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}',
    );
  }

  if (element is ClassElement) {
    for (final e in element.fields.where(
        (f) => f.isPublic && f.isConst && f.computeConstantValue() == object)) {
      return Revivable._(
        source: url.removeFragment(),
        accessor: '${element.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;
  }

  // ignore: deprecated_member_use
  for (final type in origin!.definingCompilationUnit.types) {
    for (final e in type.fields
        .where((f) => f.isConst && f.computeConstantValue() == object)) {
      final result = Revivable._(
        source: url.removeFragment(),
        accessor: '${type.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;
    }
  }
  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._({
    required 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 =>
      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';
  }
}
