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

#include "platform/assert.h"
#include "vm/assembler.h"
#include "vm/class_finalizer.h"
#include "vm/compiler.h"
#include "vm/dart_entry.h"
#include "vm/object.h"
#include "vm/resolver.h"
#include "vm/symbols.h"
#include "vm/unit_test.h"

namespace dart {

// Setup function for invocation.
static void SetupFunction(const char* test_library_name,
                          const char* test_class_name,
                          const char* test_static_function_name,
                          bool is_static) {
  // Setup a dart class and function.
  char script_chars[1024];
  OS::SNPrint(script_chars,
              sizeof(script_chars),
              "class Base {\n"
              "  dynCall() { return 3; }\n"
              "  static statCall() { return 4; }\n"
              "\n"
              "}\n"
              "class %s extends Base {\n"
              "  %s %s(String s, int i) { return i; }\n"
              "}\n",
              test_class_name,
              is_static ? "static" : "",
              test_static_function_name);

  String& url = String::Handle(is_static ?
                               String::New("dart-test:DartStaticResolve") :
                               String::New("dart-test:DartDynamicResolve"));
  String& source = String::Handle(String::New(script_chars));
  Script& script = Script::Handle(Script::New(url,
                                              source,
                                              RawScript::kScriptTag));
  const String& lib_name = String::Handle(String::New(test_library_name));
  Library& lib = Library::Handle(Library::New(lib_name));
  lib.Register();
  EXPECT(CompilerTest::TestCompileScript(lib, script));
  EXPECT(ClassFinalizer::ProcessPendingClasses());
}


// Setup a static function for invocation.
static void SetupStaticFunction(const char* test_library_name,
                                const char* test_class_name,
                                const char* test_static_function_name) {
  // Setup a static dart class and function.
  SetupFunction(test_library_name,
                test_class_name,
                test_static_function_name,
                true);
}


// Setup an instance  function for invocation.
static void SetupInstanceFunction(const char* test_library_name,
                                  const char* test_class_name,
                                  const char* test_function_name) {
  // Setup a static dart class and function.
  SetupFunction(test_library_name,
                test_class_name,
                test_function_name,
                false);
}


TEST_CASE(DartStaticResolve) {
  const char* test_library_name = "ResolverApp";
  const char* test_class_name = "A";
  const char* test_static_function_name = "static_foo";
  const int kTestValue = 42;

  // Setup a static function which can be invoked.
  SetupStaticFunction(test_library_name,
                      test_class_name,
                      test_static_function_name);

  const String& library_name = String::Handle(String::New(test_library_name));
  const Library& library =
      Library::Handle(Library::LookupLibrary(library_name));
  const String& class_name = String::Handle(String::New(test_class_name));
  const String& static_function_name =
      String::Handle(String::New(test_static_function_name));

  // Now try to resolve and invoke the static function in this class.
  {
    const int kNumArguments = 2;
    const Function& function = Function::Handle(
        Resolver::ResolveStatic(library,
                                class_name,
                                static_function_name,
                                kNumArguments,
                                Object::empty_array()));
    EXPECT(!function.IsNull());  // No ambiguity error expected.
    const Array& args = Array::Handle(Array::New(kNumArguments));
    const String& arg0 = String::Handle(String::New("junk"));
    args.SetAt(0, arg0);
    const Smi& arg1 = Smi::Handle(Smi::New(kTestValue));
    args.SetAt(1, arg1);
    const Smi& retval = Smi::Handle(
        reinterpret_cast<RawSmi*>(DartEntry::InvokeFunction(function, args)));
    EXPECT_EQ(kTestValue, retval.Value());
  }

  // Now try to resolve a static function with invalid argument count.
  {
    const int kNumArguments = 1;
    const Function& bad_function = Function::Handle(
        Resolver::ResolveStatic(library,
                                class_name,
                                static_function_name,
                                kNumArguments,
                                Object::empty_array()));
    EXPECT(bad_function.IsNull());  // No ambiguity error expected.
  }

  // Hierarchy walking.
  {
    const String& super_static_function_name =
        String::Handle(String::New("statCall"));
    const String& super_class_name = String::Handle(String::New("Base"));
    const int kNumArguments = 0;
    const Function& super_function = Function::Handle(
        Resolver::ResolveStatic(library,
                                super_class_name,
                                super_static_function_name,
                                kNumArguments,
                                Object::empty_array()));
    EXPECT(!super_function.IsNull());  // No ambiguity error expected.
  }
}


TEST_CASE(DartDynamicResolve) {
  const char* test_library_name = "ResolverApp";
  const char* test_class_name = "A";
  const char* test_function_name = "foo";
  const int kTestValue = 42;

  // Setup a function which can be invoked.
  SetupInstanceFunction(test_library_name,
                        test_class_name,
                        test_function_name);

  // Now create an instance object of the class and try to
  // resolve a function in it.
  const String& lib_name = String::Handle(String::New(test_library_name));
  const Library& lib = Library::Handle(Library::LookupLibrary(lib_name));
  ASSERT(!lib.IsNull());
  const Class& cls = Class::Handle(lib.LookupClass(
      String::Handle(Symbols::New(test_class_name))));
  EXPECT(!cls.IsNull());  // No ambiguity error expected.

  Instance& receiver = Instance::Handle(Instance::New(cls));
  const String& function_name = String::Handle(String::New(test_function_name));

  // Now try to resolve and invoke the instance function in this class.
  {
    const int kNumArguments = 3;
    ArgumentsDescriptor args_desc(
        Array::Handle(ArgumentsDescriptor::New(kNumArguments)));
    const Function& function = Function::Handle(
        Resolver::ResolveDynamic(receiver,
                                 function_name,
                                 args_desc));
    EXPECT(!function.IsNull());
    const Array& args = Array::Handle(Array::New(kNumArguments));
    args.SetAt(0, receiver);
    const String& arg0 = String::Handle(String::New("junk"));
    args.SetAt(1, arg0);
    const Smi& arg1 = Smi::Handle(Smi::New(kTestValue));
    args.SetAt(2, arg1);
    const Smi& retval = Smi::Handle(
        reinterpret_cast<RawSmi*>(DartEntry::InvokeFunction(function, args)));
    EXPECT_EQ(kTestValue, retval.Value());
  }

  // Now try to resolve an instance function with invalid argument count.
  {
    const int kNumArguments = 1;
    ArgumentsDescriptor args_desc(
        Array::Handle(ArgumentsDescriptor::New(kNumArguments)));
    const Function& bad_function = Function::Handle(
        Resolver::ResolveDynamic(receiver,
                                 function_name,
                                 args_desc));
    EXPECT(bad_function.IsNull());
  }

  // Hierarchy walking.
  {
    const int kNumArguments = 1;
    ArgumentsDescriptor args_desc(
        Array::Handle(ArgumentsDescriptor::New(kNumArguments)));
    const String& super_function_name =
        String::Handle(String::New("dynCall"));
    const Function& super_function = Function::Handle(
        Resolver::ResolveDynamic(receiver,
                                 super_function_name,
                                 args_desc));
    EXPECT(!super_function.IsNull());
  }
}

}  // namespace dart
