// Copyright (c) 2019, 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/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:analyzer/src/summary/format.dart';
import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary2/reference.dart';

class LinkingBundleContext {
  /// The `dynamic` class is declared in `dart:core`, but is not a class.
  /// Also, it is static, so we cannot set `reference` for it.
  /// So, we have to push it in a separate way.
  final Reference dynamicReference;

  /// References used in all libraries being linked.
  /// Element references in nodes are indexes in this list.
  final List<Reference> references = [null];

  /// Data about [references].
  final LinkedNodeReferencesBuilder referencesBuilder =
      LinkedNodeReferencesBuilder(
    parent: [0],
    name: [''],
  );

  LinkingBundleContext(this.dynamicReference);

  int indexOfReference(Reference reference) {
    if (reference == null) return 0;
    if (reference.parent == null) return 0;
    if (reference.index != null) return reference.index;

    var parentIndex = indexOfReference(reference.parent);
    referencesBuilder.parent.add(parentIndex);
    referencesBuilder.name.add(reference.name);

    reference.index = references.length;
    references.add(reference);
    return reference.index;
  }

  LinkedNodeTypeBuilder writeType(DartType type) {
    if (type == null) return null;

    if (type.isBottom) {
      return LinkedNodeTypeBuilder(
        kind: LinkedNodeTypeKind.bottom,
      );
    } else if (type.isDynamic) {
      return LinkedNodeTypeBuilder(
        kind: LinkedNodeTypeKind.dynamic_,
      );
    } else if (type is FunctionType) {
      return LinkedNodeTypeBuilder(
        kind: LinkedNodeTypeKind.function,
        functionFormalParameters: type.parameters
            .map((p) => LinkedNodeTypeFormalParameterBuilder(
                  // ignore: deprecated_member_use_from_same_package
                  kind: _formalParameterKind(p.parameterKind),
                  name: p.name,
                  type: writeType(p.type),
                ))
            .toList(),
        functionReturnType: writeType(type.returnType),
        functionTypeParameters: _getReferences(type.typeParameters),
      );
    } else if (type is InterfaceType) {
      return LinkedNodeTypeBuilder(
        kind: LinkedNodeTypeKind.interface,
        interfaceClass: _getReferenceIndex(type.element),
        interfaceTypeArguments: type.typeArguments.map(writeType).toList(),
      );
    } else if (type is TypeParameterType) {
      return LinkedNodeTypeBuilder(
        kind: LinkedNodeTypeKind.typeParameter,
        typeParameterParameter: _getReferenceIndex(type.element),
      );
    } else if (type is VoidType) {
      return LinkedNodeTypeBuilder(
        kind: LinkedNodeTypeKind.void_,
      );
    } else {
      throw UnimplementedError('(${type.runtimeType}) $type');
    }
  }

  LinkedNodeFormalParameterKind _formalParameterKind(ParameterKind kind) {
    if (kind == ParameterKind.NAMED) {
      return LinkedNodeFormalParameterKind.optionalNamed;
    }
    if (kind == ParameterKind.POSITIONAL) {
      return LinkedNodeFormalParameterKind.optionalPositional;
    }
    return LinkedNodeFormalParameterKind.required;
  }

  int _getReferenceIndex(Element element) {
    if (element == null) return 0;

    var reference = (element as ElementImpl).reference;
    return indexOfReference(reference);
  }

  List<int> _getReferences(List<Element> elements) {
    var result = List<int>(elements.length);
    for (var i = 0; i < elements.length; ++i) {
      var element = elements[i];
      result[i] = _getReferenceIndex(element);
    }
    return result;
  }
}
