// Copyright (c) 2015, 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/generated/resolver.dart' show TypeProvider;
import 'package:analyzer/src/generated/utilities_dart.dart';

import '../js_ast/js_ast.dart' as JS;
import 'module_compiler.dart' show CompilerOptions;
import 'js_interop.dart';

/// Mixin with logic to generate [TypeRef]s out of [DartType]s.
abstract class JSTypeRefCodegen {
  final _resolved = <DartType, JS.TypeRef>{};

  // Mixin dependencies:
  CompilerOptions get options;
  TypeProvider get types;
  LibraryElement get dartJSLibrary;
  JS.Identifier get namedArgumentTemp;
  JS.Identifier emitLibraryName(LibraryElement e);

  /// Finds the qualified path to the type.
  JS.TypeRef _emitTopLevelTypeRef(DartType type) {
    var e = type.element;
    return new JS.TypeRef.qualified([
      emitLibraryName(e.library),
      new JS.Identifier(getJSExportName(e) ?? e.name)
    ]);
  }

  JS.TypeRef emitTypeRef(DartType type) {
    if (!options.closure) return null;

    return _resolved.putIfAbsent(type, () {
      if (type == null) new JS.TypeRef.unknown();
      // TODO(ochafik): Consider calling _loader.declareBeforeUse(type.element).
      if (type.isBottom || type.isDynamic) new JS.TypeRef.any();
      if (type.isVoid) return new JS.TypeRef.void_();

      if (type == types.intType) return new JS.TypeRef.number().orNull();
      if (type == types.numType) return new JS.TypeRef.number().orNull();
      if (type == types.doubleType) return new JS.TypeRef.number().orNull();
      if (type == types.boolType) return new JS.TypeRef.boolean().orNull();
      if (type == types.stringType) return new JS.TypeRef.string();

      if (type is TypeParameterType) return new JS.TypeRef.named(type.name);
      if (type is ParameterizedType) {
        JS.TypeRef rawType;
        if (type is FunctionType && type.name == null) {
          var args = <JS.Identifier, JS.TypeRef>{};
          for (var param in type.parameters) {
            if (param.parameterKind == ParameterKind.NAMED) break;
            var type = emitTypeRef(param.type);
            args[new JS.Identifier(param.name)] =
                param.parameterKind == ParameterKind.POSITIONAL
                    ? type.toOptional()
                    : type;
          }
          var namedParamType = emitNamedParamsArgType(type.parameters);
          if (namedParamType != null) {
            args[namedArgumentTemp] = namedParamType.toOptional();
          }

          rawType = new JS.TypeRef.function(emitTypeRef(type.returnType), args);
        } else {
          var jsTypeRef = _getDartJsTypeRef(type);
          if (jsTypeRef != null) return jsTypeRef;

          rawType = _emitTopLevelTypeRef(type);
        }
        var typeArgs = _getOwnTypeArguments(type).map(emitTypeRef);
        return typeArgs.isEmpty
            ? rawType
            : new JS.TypeRef.generic(rawType, typeArgs);
      }
      return new JS.TypeRef.unknown();
    });
  }

  JS.TypeRef emitNamedParamsArgType(Iterable<ParameterElement> params) {
    if (!options.closure) return null;

    var namedArgs = <JS.Identifier, JS.TypeRef>{};
    for (ParameterElement param in params) {
      if (param.parameterKind != ParameterKind.NAMED) continue;
      namedArgs[new JS.Identifier(param.name)] =
          emitTypeRef(param.type).toOptional();
    }
    if (namedArgs.isEmpty) return null;
    return new JS.TypeRef.record(namedArgs);
  }

  /// Gets the "own" type arguments of [type].
  ///
  /// Method argument with adhoc unnamed [FunctionType] inherit any type params
  /// from their enclosing class:
  ///
  ///      class Foo<T> {
  ///        void method(f()); // f has [T] as type arguments,
  ///      }                   // but [] as its "own" type arguments.
  Iterable<DartType> _getOwnTypeArguments(ParameterizedType type) sync* {
    for (int i = 0, n = type.typeParameters.length; i < n; i++) {
      if (type.typeParameters[i].enclosingElement == type.element) {
        yield type.typeArguments[i];
      }
    }
  }

  /// Special treatment of types from dart:js
  /// TODO(ochafik): Is this the right thing to do? And what about package:js?
  JS.TypeRef _getDartJsTypeRef(DartType type) {
    if (type.element.library == dartJSLibrary) {
      switch (type.name) {
        case 'JsArray':
          return new JS.TypeRef.array(
              type is InterfaceType && type.typeArguments.length == 1
                  ? emitTypeRef(type.typeArguments.single)
                  : null);
        case 'JsObject':
          return new JS.TypeRef.object();
        case 'JsFunction':
          return new JS.TypeRef.function();
      }
    }
    return null;
  }
}
