// Copyright (c) 2014, 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.

library backend_ast_emitter;

import 'backend_ast_nodes.dart';
import '../dart_types.dart';
import '../elements/elements.dart';

class TypeGenerator {
  /// TODO(johnniwinther): Remove this when issue 21283 has been resolved.
  static int pseudoNameCounter = 0;

  static Parameter emitParameter(DartType type,
      {String name, Element element}) {
    if (name == null && element != null) {
      name = element.name;
    }
    if (name == null) {
      name = '_${pseudoNameCounter++}';
    }
    Parameter parameter;
    if (type.isFunctionType) {
      FunctionType functionType = type;
      TypeAnnotation returnType = createOptionalType(functionType.returnType);
      Parameters innerParameters = createParametersFromType(functionType);
      parameter = new Parameter.function(name, returnType, innerParameters);
    } else {
      TypeAnnotation typeAnnotation = createOptionalType(type);
      parameter = new Parameter(name, type: typeAnnotation);
    }
    parameter.element = element;
    return parameter;
  }

  static Parameters createParametersFromType(FunctionType functionType) {
    pseudoNameCounter = 0;
    if (functionType.namedParameters.isEmpty) {
      return new Parameters(createParameters(functionType.parameterTypes),
          createParameters(functionType.optionalParameterTypes), false);
    } else {
      return new Parameters(
          createParameters(functionType.parameterTypes),
          createParameters(functionType.namedParameterTypes,
              names: functionType.namedParameters),
          true);
    }
  }

  static List<Parameter> createParameters(Iterable<DartType> parameterTypes,
      {Iterable<String> names: const <String>[],
      Iterable<Element> elements: const <Element>[]}) {
    Iterator<String> name = names.iterator;
    Iterator<Element> element = elements.iterator;
    return parameterTypes.map((DartType type) {
      name.moveNext();
      element.moveNext();
      return emitParameter(type, name: name.current, element: element.current);
    }).toList();
  }

  /// Like [createTypeAnnotation] except the dynamic type is converted to null.
  static TypeAnnotation createOptionalType(DartType type) {
    if (type.treatAsDynamic) {
      return null;
    } else {
      return createType(type);
    }
  }

  /// Creates the [TypeAnnotation] for a [type] that is not function type.
  static TypeAnnotation createType(DartType type) {
    if (type is GenericType) {
      if (type.treatAsRaw) {
        return new TypeAnnotation(type.element.name)..dartType = type;
      }
      return new TypeAnnotation(type.element.name,
          type.typeArguments.map(createType).toList(growable: false))
        ..dartType = type;
    } else if (type is VoidType) {
      return new TypeAnnotation('void')..dartType = type;
    } else if (type is TypeVariableType) {
      return new TypeAnnotation(type.name)..dartType = type;
    } else if (type is DynamicType) {
      return new TypeAnnotation("dynamic")..dartType = type;
    } else if (type is MalformedType) {
      return new TypeAnnotation(type.name)..dartType = type;
    } else {
      throw "Unsupported type annotation: $type";
    }
  }
}
