// Copyright 2026 Google LLC
//
// 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 "async/cancellation_token.h"

#include <optional>

#include "gtest/gtest.h"

namespace credentio {
namespace {

TEST(CancellationTokenTest, IsCancelledFalseInitially) {
  CancellationSource source;
  CancellationToken token = source.GetToken();
  EXPECT_FALSE(token.IsCancelled());
}

TEST(CancellationTokenTest, IsCancelledTrueAfterCancel) {
  CancellationSource source;
  CancellationToken token = source.GetToken();
  source.Cancel();
  EXPECT_TRUE(token.IsCancelled());
}

TEST(CancellationTokenTest, CallbackExecutedOnCancel) {
  CancellationSource source;
  CancellationToken token = source.GetToken();

  bool executed = false;
  CancellationCallback callback(token, [&executed]() { executed = true; });

  EXPECT_FALSE(executed);
  source.Cancel();
  EXPECT_TRUE(executed);
}

TEST(CancellationTokenTest, CallbackNotExecutedIfDeregistered) {
  CancellationSource source;
  CancellationToken token = source.GetToken();

  bool executed = false;
  {
    CancellationCallback callback(token, [&executed]() { executed = true; });
  }  // callback destroyed here

  source.Cancel();
  EXPECT_FALSE(executed);
}

TEST(CancellationTokenTest, CallbackExecutedImmediatelyIfAlreadyCancelled) {
  CancellationSource source;
  CancellationToken token = source.GetToken();
  source.Cancel();

  bool executed = false;
  CancellationCallback callback(token, [&executed]() { executed = true; });

  // Execute happens inline during registration
  EXPECT_TRUE(executed);
}

TEST(CancellationTokenTest, MultipleCallbacks) {
  CancellationSource source;
  CancellationToken token = source.GetToken();

  bool ex1 = false;
  bool ex2 = false;

  CancellationCallback cb1(token, [&ex1]() { ex1 = true; });
  CancellationCallback cb2(token, [&ex2]() { ex2 = true; });

  source.Cancel();
  EXPECT_TRUE(ex1);
  EXPECT_TRUE(ex2);
}

TEST(CancellationTokenTest, UncancellableToken) {
  CancellationToken token;  // Default constructed
  EXPECT_FALSE(token.IsCancelled());

  bool executed = false;
  CancellationCallback callback(token, [&executed]() { executed = true; });

  // Can never be cancelled
  EXPECT_FALSE(executed);
}

// Ensure the token can outlive the source safely.
TEST(CancellationTokenTest, TokenOutlivesSource) {
  std::optional<CancellationToken> token;
  {
    CancellationSource source;
    token = source.GetToken();
  }

  // Checking IsCancelled should be safe and return false
  EXPECT_FALSE(token->IsCancelled());

  // Registering callback should be safe (and it will never fire)
  bool executed = false;
  CancellationCallback callback(*token, [&executed]() { executed = true; });
  EXPECT_FALSE(executed);
}

}  // namespace
}  // namespace credentio
