// Copyright 2020 The Pigweed Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.

#include "gtest/gtest.h"
#include "pw_sync/interrupt_spin_lock.h"

namespace pw::sync {
namespace {

extern "C" {

// Functions defined in interrupt_spin_lock_facade_test_c.c which call the API
// from C.
void pw_sync_InterruptSpinLock_CallLock(
    pw_sync_InterruptSpinLock* interrupt_spin_lock);
bool pw_sync_InterruptSpinLock_CallTryLock(
    pw_sync_InterruptSpinLock* interrupt_spin_lock);
void pw_sync_InterruptSpinLock_CallUnlock(
    pw_sync_InterruptSpinLock* interrupt_spin_lock);

}  // extern "C"

TEST(InterruptSpinLock, LockUnlock) {
  pw::sync::InterruptSpinLock interrupt_spin_lock;
  interrupt_spin_lock.lock();
  interrupt_spin_lock.unlock();
}

// TODO(pwbug/291): Add real concurrency tests once we have pw::thread on SMP
// systems given that uniprocessor systems cannot fail to acquire an ISL.

InterruptSpinLock static_interrupt_spin_lock;
TEST(InterruptSpinLock, LockUnlockStatic) {
  static_interrupt_spin_lock.lock();
  // TODO(pwbug/291): Ensure other cores fail to lock when its locked.
  // EXPECT_FALSE(static_interrupt_spin_lock.try_lock());
  static_interrupt_spin_lock.unlock();
}

TEST(InterruptSpinLock, TryLockUnlock) {
  pw::sync::InterruptSpinLock interrupt_spin_lock;
  const bool locked = interrupt_spin_lock.try_lock();
  EXPECT_TRUE(locked);
  if (locked) {
    // TODO(pwbug/291): Ensure other cores fail to lock when its locked.
    // EXPECT_FALSE(interrupt_spin_lock.try_lock());
    interrupt_spin_lock.unlock();
  }
}

TEST(VirtualInterruptSpinLock, LockUnlock) {
  pw::sync::VirtualInterruptSpinLock interrupt_spin_lock;
  interrupt_spin_lock.lock();
  // TODO(pwbug/291): Ensure other cores fail to lock when its locked.
  // EXPECT_FALSE(interrupt_spin_lock.try_lock());
  interrupt_spin_lock.unlock();
}

VirtualInterruptSpinLock static_virtual_interrupt_spin_lock;
TEST(VirtualInterruptSpinLock, LockUnlockStatic) {
  static_virtual_interrupt_spin_lock.lock();
  // TODO(pwbug/291): Ensure other cores fail to lock when its locked.
  // EXPECT_FALSE(static_virtual_interrupt_spin_lock.try_lock());
  static_virtual_interrupt_spin_lock.unlock();
}

TEST(InterruptSpinLock, LockUnlockInC) {
  pw::sync::InterruptSpinLock interrupt_spin_lock;
  pw_sync_InterruptSpinLock_CallLock(&interrupt_spin_lock);
  pw_sync_InterruptSpinLock_CallUnlock(&interrupt_spin_lock);
}

TEST(InterruptSpinLock, TryLockUnlockInC) {
  pw::sync::InterruptSpinLock interrupt_spin_lock;
  ASSERT_TRUE(pw_sync_InterruptSpinLock_CallTryLock(&interrupt_spin_lock));
  // TODO(pwbug/291): Ensure other cores fail to lock when its locked.
  // EXPECT_FALSE(pw_sync_InterruptSpinLock_CallTryLock(&interrupt_spin_lock));
  pw_sync_InterruptSpinLock_CallUnlock(&interrupt_spin_lock);
}

}  // namespace
}  // namespace pw::sync
