// 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 dart_precompiled_runtime.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_dart_precompiled_runtime = 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_dart_precompiled_runtime) {                                          \
    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_dart_precompiled_runtime) {                                          \
    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_dart_precompiled_runtime = 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);
}
