// 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 "vm/handles.h"
#include "platform/assert.h"
#include "vm/dart_api_state.h"
#include "vm/flags.h"
#include "vm/object.h"
#include "vm/unit_test.h"
#include "vm/zone.h"

namespace dart {

// Unit test for Zone handle allocation.
ISOLATE_UNIT_TEST_CASE(AllocateZoneHandle) {
#if defined(DEBUG)
  FLAG_trace_handles = true;
#endif
  // The previously run stub code generation may have created zone handles.
  int initial_count = VMHandles::ZoneHandleCount();
  const int kNumHandles = 65;
  // Create some zone handles.
  for (int i = 0; i < kNumHandles; i++) {
    const Smi& handle = Smi::ZoneHandle(Smi::New(i));
    EXPECT(handle.IsSmi());
    EXPECT_EQ(i, handle.Value());
  }
  EXPECT_EQ(kNumHandles + initial_count, VMHandles::ZoneHandleCount());
  // Create some more zone handles.
  for (int i = kNumHandles; i < (2 * kNumHandles); i++) {
    const Smi& handle = Smi::ZoneHandle(Smi::New(i));
    EXPECT(handle.IsSmi());
    EXPECT_EQ(i, handle.Value());
  }
  EXPECT_EQ((2 * kNumHandles) + initial_count, VMHandles::ZoneHandleCount());
}

// Unit test for Scope handle allocation.
ISOLATE_UNIT_TEST_CASE(AllocateScopeHandle) {
#if defined(DEBUG)
  FLAG_trace_handles = true;
#endif
  int32_t handle_count = VMHandles::ScopedHandleCount();
  const int kNumHandles = 65;
  // Create some scoped handles.
  {
    Thread* thread = Thread::Current();
    HANDLESCOPE(thread);
    for (int i = 0; i < kNumHandles; i++) {
      const Smi& handle = Smi::Handle(Smi::New(i));
      EXPECT(handle.IsSmi());
      EXPECT_EQ(i, handle.Value());
    }
    EXPECT_EQ((handle_count + kNumHandles), VMHandles::ScopedHandleCount());
    // Create lots of scoped handles in a loop with a nested scope.
    for (int loop = 0; loop < 1000; loop++) {
      HANDLESCOPE(thread);
      for (int i = 0; i < 2; i++) {
        const Smi& handle = Smi::Handle(Smi::New(i + loop));
        EXPECT(handle.IsSmi());
        EXPECT_EQ(i + loop, handle.Value());
      }
      EXPECT_EQ((handle_count + kNumHandles + 2),
                VMHandles::ScopedHandleCount());
    }
    EXPECT_EQ((handle_count + kNumHandles), VMHandles::ScopedHandleCount());
    for (int i = 0; i < kNumHandles; i++) {
      const Smi& handle = Smi::Handle(Smi::New(i));
      EXPECT(handle.IsSmi());
      EXPECT_EQ(i, handle.Value());
    }
    EXPECT_EQ((handle_count + (2 * kNumHandles)),
              VMHandles::ScopedHandleCount());
  }
  EXPECT_EQ(handle_count, VMHandles::ScopedHandleCount());
}

static void NoopCallback(void* isolate_callback_data, void* peer) {}

// Unit test for handle validity checks.
TEST_CASE(CheckHandleValidity) {
#if defined(DEBUG)
  FLAG_trace_handles = true;
#endif
  Dart_Handle handle = nullptr;
  // Check validity using zone handles.
  {
    TransitionNativeToVM transition(thread);
    StackZone sz(thread);
    handle = reinterpret_cast<Dart_Handle>(&Smi::ZoneHandle(Smi::New(1)));
    {
      TransitionVMToNative to_native(thread);
      EXPECT_VALID(handle);
    }
  }
  EXPECT(!Api::IsValid(handle));

  // Check validity using scoped handles.
  {
    Dart_EnterScope();
    {
      TransitionNativeToVM transition(thread);
      HANDLESCOPE(thread);
      handle = reinterpret_cast<Dart_Handle>(&Smi::Handle(Smi::New(1)));
      {
        TransitionVMToNative to_native(thread);
        EXPECT_VALID(handle);
      }
    }
    Dart_ExitScope();
  }
  EXPECT(!Api::IsValid(handle));

  // Check validity using persistent handle.
  Dart_Handle scoped_handle;
  {
    TransitionNativeToVM transition(thread);
    scoped_handle = Api::NewHandle(thread, Smi::New(1));
  }
  Dart_PersistentHandle persistent_handle =
      Dart_NewPersistentHandle(scoped_handle);
  EXPECT_VALID(persistent_handle);

  Dart_DeletePersistentHandle(persistent_handle);
  EXPECT(!Api::IsValid(persistent_handle));

  // Check validity using weak persistent handle.
  handle = reinterpret_cast<Dart_Handle>(Dart_NewWeakPersistentHandle(
      Dart_NewStringFromCString("foo"), nullptr, 0, NoopCallback));

  EXPECT_NOTNULL(handle);
  EXPECT_VALID(handle);

  Dart_DeleteWeakPersistentHandle(
      reinterpret_cast<Dart_WeakPersistentHandle>(handle));
  EXPECT(!Api::IsValid(handle));
}

}  // namespace dart
