// 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.computeArity());
    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));
  }
}
