// Copyright (c) 2019, 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 <stdio.h>
#include <stdlib.h>
#include <string.h>

// TODO(dartbug.com/40579): This requires static linking to either link
// dart.exe or dartaotruntime.exe on Windows.
// The sample currently fails on Windows in AOT mode.
#include "include/dart_api.h"
#include "include/dart_native_api.h"

#define CHECK(H)                                                               \
  do {                                                                         \
    Dart_Handle __handle__ = H;                                                \
    if (Dart_IsError(__handle__)) {                                            \
      const char* message = Dart_GetError(__handle__);                         \
      fprintf(stderr, "Check \"" #H "\" failed: %s", message);                 \
      abort();                                                                 \
    }                                                                          \
  } while (false)

#define ASSERT(E)                                                              \
  if (!(E)) {                                                                  \
    fprintf(stderr, "Assertion \"" #E "\" failed at %s:%d!\n", __FILE__,       \
            __LINE__);                                                         \
    abort();                                                                   \
  }

static bool is_dartaotruntime = true;

// Some invalid accesses are allowed in AOT since we don't retain @pragma
// annotations. Therefore we skip the negative tests in AOT.
#define FAIL(name, result)                                                     \
  if (!is_dartaotruntime) {                                                    \
    Fail(name, result);                                                        \
  }

void Fail(const char* name, Dart_Handle result) {
  ASSERT(Dart_IsApiError(result));
  const char* error = Dart_GetError(result);
  ASSERT(strstr(error, name));
  ASSERT(strstr(error, "It is illegal to access"));
}

#define FAIL_INVOKE_FIELD(name, result)                                        \
  if (!is_dartaotruntime) {                                                    \
    FailInvokeField(name, result);                                             \
  }

static void FailInvokeField(const char* name, Dart_Handle result) {
  ASSERT(Dart_IsApiError(result));
  const char* error = Dart_GetError(result);
  ASSERT(strstr(error, name));
  ASSERT(strstr(error, "Entry-points do not allow invoking fields"));
}

static void FailClosurizeConstructor(const char* name, Dart_Handle result) {
  ASSERT(Dart_IsUnhandledExceptionError(result));
  const char* error = Dart_GetError(result);
  ASSERT(strstr(error, name));
  ASSERT(strstr(error, "No static getter"));
}

static void TestFields(Dart_Handle target) {
  FAIL("fld0", Dart_GetField(target, Dart_NewStringFromCString("fld0")));
  FAIL("fld0",
       Dart_SetField(target, Dart_NewStringFromCString("fld0"), Dart_Null()));

  FAIL_INVOKE_FIELD(
      "fld0",
      Dart_Invoke(target, Dart_NewStringFromCString("fld0"), 0, nullptr));

  CHECK(Dart_GetField(target, Dart_NewStringFromCString("fld1")));
  CHECK(Dart_SetField(target, Dart_NewStringFromCString("fld1"), Dart_Null()));
  FAIL_INVOKE_FIELD(
      "fld1",
      Dart_Invoke(target, Dart_NewStringFromCString("fld1"), 0, nullptr));

  CHECK(Dart_GetField(target, Dart_NewStringFromCString("fld2")));
  FAIL("fld2",
       Dart_SetField(target, Dart_NewStringFromCString("fld2"), Dart_Null()));
  FAIL_INVOKE_FIELD(
      "fld2",
      Dart_Invoke(target, Dart_NewStringFromCString("fld2"), 0, nullptr));

  FAIL("fld3", Dart_GetField(target, Dart_NewStringFromCString("fld3")));
  CHECK(Dart_SetField(target, Dart_NewStringFromCString("fld3"), Dart_Null()));
  FAIL_INVOKE_FIELD(
      "fld3",
      Dart_Invoke(target, Dart_NewStringFromCString("fld3"), 0, nullptr));
}

DART_EXPORT void RunTests() {
  is_dartaotruntime = Dart_IsPrecompiledRuntime();

  Dart_Handle lib = Dart_RootLibrary();

  //////// Test allocation and constructor invocation.

  FAIL("C", Dart_GetClass(lib, Dart_NewStringFromCString("C")));

  Dart_Handle D_class = Dart_GetClass(lib, Dart_NewStringFromCString("D"));
  CHECK(D_class);

  CHECK(Dart_Allocate(D_class));

  FAIL("D.", Dart_New(D_class, Dart_Null(), 0, nullptr));

  CHECK(Dart_New(D_class, Dart_NewStringFromCString("defined"), 0, nullptr));
  Dart_Handle D =
      Dart_New(D_class, Dart_NewStringFromCString("fact"), 0, nullptr);
  CHECK(D);

  //////// Test actions against methods

  FailClosurizeConstructor(
      "defined", Dart_GetField(D_class, Dart_NewStringFromCString("defined")));
  FailClosurizeConstructor(
      "fact", Dart_GetField(D_class, Dart_NewStringFromCString("fact")));

  FAIL("fn0", Dart_Invoke(D, Dart_NewStringFromCString("fn0"), 0, nullptr));

  CHECK(Dart_Invoke(D, Dart_NewStringFromCString("fn1"), 0, nullptr));
  FAIL("fn1", Dart_Invoke(D, Dart_NewStringFromCString("fn1_get"), 0, nullptr));
  CHECK(Dart_Invoke(D, Dart_NewStringFromCString("fn1_call"), 0, nullptr));

  FAIL("fn0", Dart_GetField(D, Dart_NewStringFromCString("fn0")));

  CHECK(Dart_GetField(D, Dart_NewStringFromCString("fn1")));
  CHECK(Dart_GetField(D, Dart_NewStringFromCString("fn1_get")));
  FAIL("fn1", Dart_GetField(D, Dart_NewStringFromCString("fn1_call")));

  FAIL("fn2",
       Dart_Invoke(D_class, Dart_NewStringFromCString("fn2"), 0, nullptr));

  CHECK(Dart_Invoke(D_class, Dart_NewStringFromCString("fn3"), 0, nullptr));
  CHECK(
      Dart_Invoke(D_class, Dart_NewStringFromCString("fn3_call"), 0, nullptr));
  FAIL("fn3",
       Dart_Invoke(D_class, Dart_NewStringFromCString("fn3_get"), 0, nullptr));

  FAIL("fn2", Dart_GetField(D_class, Dart_NewStringFromCString("fn2")));

  CHECK(Dart_GetField(D_class, Dart_NewStringFromCString("fn3")));
  FAIL("fn3_call",
       Dart_GetField(D_class, Dart_NewStringFromCString("fn3_call")));
  CHECK(Dart_GetField(D_class, Dart_NewStringFromCString("fn3_get")));

  FAIL("fn0", Dart_Invoke(lib, Dart_NewStringFromCString("fn0"), 0, nullptr));

  CHECK(Dart_Invoke(lib, Dart_NewStringFromCString("fn1"), 0, nullptr));
  FAIL("fn1",
       Dart_Invoke(lib, Dart_NewStringFromCString("fn1_get"), 0, nullptr));
  CHECK(Dart_Invoke(lib, Dart_NewStringFromCString("fn1_call"), 0, nullptr));

  FAIL("fn0", Dart_GetField(lib, Dart_NewStringFromCString("fn0")));

  CHECK(Dart_GetField(lib, Dart_NewStringFromCString("fn1")));
  CHECK(Dart_GetField(lib, Dart_NewStringFromCString("fn1_get")));
  FAIL("fn1", Dart_GetField(lib, Dart_NewStringFromCString("fn1_call")));

  //////// Test actions against fields

  TestFields(D);

  Dart_Handle F_class = Dart_GetClass(lib, Dart_NewStringFromCString("F"));
  TestFields(F_class);

  TestFields(lib);
}
