// 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.

import '../common.dart';
import '../compiler.dart' show Compiler;
import '../constants/values.dart';
import '../elements/resolution_types.dart';
import '../elements/elements.dart';
import '../js/js.dart' as js;
import '../js_backend/js_backend.dart';
import '../js_emitter/js_emitter.dart' show NativeEmitter;
import '../ssa/builder.dart' show SsaBuilder;
import '../ssa/nodes.dart' show HInstruction, HForeignCode, HReturn;
import '../tree/tree.dart';
import '../universe/side_effects.dart' show SideEffects;

final RegExp nativeRedirectionRegExp = new RegExp(r'^[a-zA-Z][a-zA-Z_$0-9]*$');

void handleSsaNative(SsaBuilder builder, Expression nativeBody) {
  Compiler compiler = builder.compiler;
  MethodElement element = builder.target;
  NativeEmitter nativeEmitter = builder.nativeEmitter;
  JavaScriptBackend backend = builder.backend;
  DiagnosticReporter reporter = compiler.reporter;

  HInstruction convertDartClosure(
      ParameterElement parameter, ResolutionFunctionType type) {
    HInstruction local = builder.localsHandler.readLocal(parameter);
    ConstantValue arityConstant =
        builder.constantSystem.createInt(type.parameterTypes.length);
    HInstruction arity =
        builder.graph.addConstant(arityConstant, builder.closedWorld);
    // TODO(ngeoffray): For static methods, we could pass a method with a
    // defined arity.
    Element helper = backend.helpers.closureConverter;
    builder.pushInvokeStatic(nativeBody, helper, [local, arity]);
    HInstruction closure = builder.pop();
    return closure;
  }

  // Check which pattern this native method follows:
  // 1) foo() native;
  //      hasBody = false
  // 2) foo() native "bar";
  //      No longer supported, this is now done with @JSName('foo') and case 1.
  // 3) foo() native "return 42";
  //      hasBody = true
  bool hasBody = false;
  assert(backend.isNative(element));
  String nativeMethodName = backend.nativeData.getFixedBackendName(element);
  if (nativeBody != null) {
    LiteralString jsCode = nativeBody.asLiteralString();
    String str = jsCode.dartString.slowToString();
    if (nativeRedirectionRegExp.hasMatch(str)) {
      reporter.internalError(
          nativeBody, "Deprecated syntax, use @JSName('name') instead.");
    }
    hasBody = true;
  }

  if (!hasBody) {
    nativeEmitter.nativeMethods.add(element);
  }

  FunctionSignature parameters = element.functionSignature;
  if (!hasBody) {
    List<String> arguments = <String>[];
    List<HInstruction> inputs = <HInstruction>[];
    String receiver = '';
    if (element.isInstanceMember) {
      receiver = '#.';
      inputs.add(builder.localsHandler.readThis());
    }
    parameters.forEachParameter((ParameterElement parameter) {
      ResolutionDartType type = parameter.type.unaliased;
      HInstruction input = builder.localsHandler.readLocal(parameter);
      if (type is ResolutionFunctionType) {
        // The parameter type is a function type either directly or through
        // typedef(s).
        input = convertDartClosure(parameter, type);
      }
      inputs.add(input);
      arguments.add('#');
    });

    String foreignParameters = arguments.join(',');
    String nativeMethodCall;
    if (element.kind == ElementKind.FUNCTION) {
      nativeMethodCall = '$receiver$nativeMethodName($foreignParameters)';
    } else if (element.kind == ElementKind.GETTER) {
      nativeMethodCall = '$receiver$nativeMethodName';
    } else if (element.kind == ElementKind.SETTER) {
      nativeMethodCall = '$receiver$nativeMethodName = $foreignParameters';
    } else {
      builder.reporter
          .internalError(element, 'Unexpected kind: "${element.kind}".');
    }

    builder.push(new HForeignCode(
        // TODO(sra): This could be cached.  The number of templates should
        // be proportional to the number of native methods, which is bounded
        // by the dart: libraries.
        js.js.uncachedExpressionTemplate(nativeMethodCall),
        builder.commonMasks.dynamicType,
        inputs,
        effects: new SideEffects()));
    // TODO(johnniwinther): Provide source information.
    builder
        .close(new HReturn(builder.pop(), null))
        .addSuccessor(builder.graph.exit);
  } else {
    if (parameters.parameterCount != 0) {
      reporter.internalError(
          nativeBody,
          'native "..." syntax is restricted to '
          'functions with zero parameters.');
    }
    LiteralString jsCode = nativeBody.asLiteralString();
    builder.push(new HForeignCode.statement(
        js.js.statementTemplateYielding(
            new js.LiteralStatement(jsCode.dartString.slowToString())),
        <HInstruction>[],
        new SideEffects(),
        null,
        builder.commonMasks.dynamicType));
  }
}
