// 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 "tracing/tracer.h"

#include <cstdint>
#include <memory>
#include <string>
#include <thread>  // NOLINT(build/c++11)
#include <vector>

#include "absl/base/nullability.h"
#include "absl/status/status.h"
#include "absl/strings/string_view.h"
#include "async/async_context.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "tracing/noop_tracing.h"
#include "tracing/scoped_span.h"
#include "tracing/scoped_tracer_factory.h"
#include "tracing/span.h"
#include "tracing/thread_context.h"
#include "tracing/tracer_factory.h"

namespace credentio_tracing {
namespace {

using ::testing::_;
using ::testing::Eq;
using ::testing::Return;
using ::testing::StrictMock;

class MockTracer : public Tracer {
 public:
  MOCK_METHOD(std::unique_ptr<Span>, StartSpanImpl,
              (absl::string_view span_name, const StartSpanOptions& options),
              (const, override));
};

class MockTracerFactory : public TracerFactory {
 public:
  MOCK_METHOD(absl_nonnull std::shared_ptr<Tracer>, GetTracer,
              (absl::string_view tracer_name), (const, override));
};

TEST(StartSpanOptionsTest, DefaultOptions) {
  StartSpanOptions options;
  EXPECT_EQ(options.parent, nullptr);
  EXPECT_TRUE(options.attributes.empty());
}

TEST(StartSpanOptionsTest, CustomOptions) {
  NoopSpan parent_span;
  StartSpanOptions options;
  options.parent = &parent_span;
  options.attributes.push_back({"key1", std::string("val1")});
  options.attributes.push_back({"key2", int64_t{100}});

  EXPECT_EQ(options.parent, &parent_span);
  ASSERT_EQ(options.attributes.size(), 2);
  EXPECT_EQ(options.attributes[0].first, "key1");
  EXPECT_EQ(std::get<std::string>(options.attributes[0].second), "val1");
  EXPECT_EQ(options.attributes[1].first, "key2");
  EXPECT_EQ(std::get<int64_t>(options.attributes[1].second), 100);
}

TEST(TracerTest, StartSpanInvocation) {
  StrictMock<MockTracer> mock_tracer;
  EXPECT_CALL(mock_tracer, StartSpanImpl(Eq("test_span"), _))
      .WillOnce([](absl::string_view, const StartSpanOptions& options) {
        EXPECT_EQ(options.parent, nullptr);
        return std::make_unique<NoopSpan>();
      });

  std::unique_ptr<Span> span = mock_tracer.StartSpan("test_span", {});
  EXPECT_NE(span, nullptr);
}

TEST(TracerTest, StartSpanSingleArgumentOverload) {
  StrictMock<MockTracer> mock_tracer;
  EXPECT_CALL(mock_tracer, StartSpanImpl(Eq("simple_span"), _))
      .WillOnce([](absl::string_view, const StartSpanOptions& options) {
        EXPECT_EQ(options.parent, nullptr);
        EXPECT_TRUE(options.attributes.empty());
        return std::make_unique<NoopSpan>();
      });

  std::unique_ptr<Span> span = mock_tracer.StartSpan("simple_span");
  EXPECT_NE(span, nullptr);
}

TEST(TracerTest, StartSpanImplicitParentFromThreadContext) {
  NoopSpan active_thread_span;
  ThreadContext::SetCurrentSpan(&active_thread_span);

  StrictMock<MockTracer> mock_tracer;
  EXPECT_CALL(mock_tracer, StartSpanImpl(Eq("child_span"), _))
      .WillOnce([&active_thread_span](absl::string_view,
                                      const StartSpanOptions& options) {
        EXPECT_EQ(options.parent, &active_thread_span);
        return std::make_unique<NoopSpan>();
      });

  std::unique_ptr<Span> span = mock_tracer.StartSpan("child_span");
  EXPECT_NE(span, nullptr);

  ThreadContext::SetCurrentSpan(nullptr);
}

TEST(TracerTest, StartSpanExplicitParentOverridesThreadContext) {
  NoopSpan active_thread_span;
  NoopSpan explicit_parent_span;
  ThreadContext::SetCurrentSpan(&active_thread_span);

  StrictMock<MockTracer> mock_tracer;
  StartSpanOptions options;
  options.parent = &explicit_parent_span;

  EXPECT_CALL(mock_tracer, StartSpanImpl(Eq("child_span"), _))
      .WillOnce([&explicit_parent_span](absl::string_view,
                                        const StartSpanOptions& options) {
        EXPECT_EQ(options.parent, &explicit_parent_span);
        return std::make_unique<NoopSpan>();
      });

  std::unique_ptr<Span> span = mock_tracer.StartSpan("child_span", options);
  EXPECT_NE(span, nullptr);

  ThreadContext::SetCurrentSpan(nullptr);
}

TEST(TracerFactoryTest, GetTracerInvocation) {
  StrictMock<MockTracerFactory> mock_factory;
  auto mock_tracer = std::make_shared<StrictMock<MockTracer>>();

  EXPECT_CALL(mock_factory, GetTracer(Eq("mock_tracer")))
      .WillOnce(Return(mock_tracer));

  std::shared_ptr<Tracer> tracer = mock_factory.GetTracer("mock_tracer");
  EXPECT_EQ(tracer, mock_tracer);
}

TEST(TracerFactoryTest, DefaultGlobalFactoryIsNoopTracerFactory) {
  auto factory = TracerFactory::GetGlobalFactory();
  ASSERT_NE(factory, nullptr);
  auto tracer = factory->GetTracer("mock_tracer");
  ASSERT_NE(tracer, nullptr);
  auto span = tracer->StartSpan("test_span", {});
  ASSERT_NE(span, nullptr);
}

TEST(TracerFactoryTest, GlobalFactoryRegistration) {
  auto initial_factory = TracerFactory::GetGlobalFactory();
  EXPECT_NE(initial_factory, nullptr);

  auto custom_factory = std::make_shared<StrictMock<MockTracerFactory>>();
  TracerFactory::RegisterGlobalFactory(custom_factory);

  EXPECT_EQ(TracerFactory::GetGlobalFactory(), custom_factory);

  // Restore original factory state after test
  TracerFactory::RegisterGlobalFactory(initial_factory);
}

TEST(TracerFactoryTest, RegisterNullptrResetsToNoopTracerFactory) {
  auto initial_factory = TracerFactory::GetGlobalFactory();
  EXPECT_NE(initial_factory, nullptr);

  auto custom_factory = std::make_shared<StrictMock<MockTracerFactory>>();
  TracerFactory::RegisterGlobalFactory(custom_factory);
  EXPECT_EQ(TracerFactory::GetGlobalFactory(), custom_factory);

  TracerFactory::RegisterGlobalFactory(nullptr);
  auto current_factory = TracerFactory::GetGlobalFactory();
  ASSERT_NE(current_factory, nullptr);
  EXPECT_NE(current_factory, custom_factory);

  // Restore original factory state after test
  TracerFactory::RegisterGlobalFactory(initial_factory);
}

TEST(TracerFactoryTest, ConcurrentGlobalFactoryAccess) {
  constexpr int kNumThreads = 8;
  constexpr int kIterations = 100;

  std::vector<std::thread> threads;
  threads.reserve(kNumThreads);

  for (int i = 0; i < kNumThreads; ++i) {
    threads.emplace_back([&]() {
      for (int j = 0; j < kIterations; ++j) {
        auto factory = TracerFactory::GetGlobalFactory();
        EXPECT_NE(factory, nullptr);
        auto tracer = factory->GetTracer("concurrent_test");
        EXPECT_NE(tracer, nullptr);
        auto span = tracer->StartSpan("concurrent_span", {});
        EXPECT_NE(span, nullptr);
      }
    });
  }

  for (auto& t : threads) {
    t.join();
  }
}

TEST(TracerFactoryResolutionTest, FallsBackToGlobalFactory) {
  auto initial_factory = TracerFactory::GetGlobalFactory();
  auto global_factory = std::make_shared<StrictMock<MockTracerFactory>>();
  TracerFactory::RegisterGlobalFactory(global_factory);

  EXPECT_EQ(TracerFactory::Get(), global_factory);
  EXPECT_EQ(ResolveTracerFactory(credentio::AsyncContext()), global_factory);

  TracerFactory::RegisterGlobalFactory(initial_factory);
}

TEST(TracerFactoryResolutionTest, ThreadLocalFactoryShadowsGlobal) {
  auto initial_factory = TracerFactory::GetGlobalFactory();
  auto global_factory = std::make_shared<StrictMock<MockTracerFactory>>();
  auto thread_local_factory = std::make_shared<StrictMock<MockTracerFactory>>();
  TracerFactory::RegisterGlobalFactory(global_factory);

  {
    ScopedTracerFactory guard(thread_local_factory);
    EXPECT_EQ(TracerFactory::Get(), thread_local_factory);
    EXPECT_EQ(ResolveTracerFactory(credentio::AsyncContext()),
              thread_local_factory);
  }

  EXPECT_EQ(TracerFactory::GetThreadLocalFactory(), nullptr);
  EXPECT_EQ(TracerFactory::Get(), global_factory);

  TracerFactory::RegisterGlobalFactory(initial_factory);
}

TEST(TracerFactoryResolutionTest, ContextFactoryShadowsThreadLocalAndGlobal) {
  auto initial_factory = TracerFactory::GetGlobalFactory();
  auto global_factory = std::make_shared<StrictMock<MockTracerFactory>>();
  auto thread_local_factory = std::make_shared<StrictMock<MockTracerFactory>>();
  auto context_factory = std::make_shared<StrictMock<MockTracerFactory>>();
  TracerFactory::RegisterGlobalFactory(global_factory);
  ScopedTracerFactory guard(thread_local_factory);

  credentio::AsyncContext context;
  context.SetExtension<TracerFactory>(context_factory);
  EXPECT_EQ(ResolveTracerFactory(context), context_factory);

  TracerFactory::RegisterGlobalFactory(initial_factory);
}

TEST(TracerFactoryResolutionTest, ScopedTracerFactoryRestoresPrevious) {
  auto outer = std::make_shared<StrictMock<MockTracerFactory>>();
  auto inner = std::make_shared<StrictMock<MockTracerFactory>>();

  {
    ScopedTracerFactory outer_guard(outer);
    EXPECT_EQ(TracerFactory::GetThreadLocalFactory(), outer);
    {
      ScopedTracerFactory inner_guard(inner);
      EXPECT_EQ(TracerFactory::GetThreadLocalFactory(), inner);
    }
    EXPECT_EQ(TracerFactory::GetThreadLocalFactory(), outer);
  }
  EXPECT_EQ(TracerFactory::GetThreadLocalFactory(), nullptr);
}

TEST(TracerFactoryResolutionTest, ThreadLocalFactoryDoesNotLeakAcrossThreads) {
  auto initial_factory = TracerFactory::GetGlobalFactory();
  auto global_factory = std::make_shared<StrictMock<MockTracerFactory>>();
  auto thread_local_factory = std::make_shared<StrictMock<MockTracerFactory>>();
  TracerFactory::RegisterGlobalFactory(global_factory);

  ScopedTracerFactory guard(thread_local_factory);

  // A thread-local factory covers only the installing thread, which is why
  // asynchronous work needs the factory on the context instead.
  std::shared_ptr<TracerFactory> seen_without_context;
  std::shared_ptr<TracerFactory> seen_with_context;
  auto context_factory = std::make_shared<StrictMock<MockTracerFactory>>();
  credentio::AsyncContext context;
  context.SetExtension<TracerFactory>(context_factory);

  std::thread worker([&]() {
    seen_without_context = TracerFactory::Get();
    seen_with_context = ResolveTracerFactory(context);
  });
  worker.join();

  EXPECT_EQ(seen_without_context, global_factory);
  EXPECT_EQ(seen_with_context, context_factory);

  TracerFactory::RegisterGlobalFactory(initial_factory);
}

TEST(NoopSpanTest, AllMethodsExecuteWithoutError) {
  NoopSpan span;

  span.SetAttribute("key_str", std::string("value"));
  span.SetAttribute("key_int", int64_t{42});
  span.SetAttribute("key_double", 3.14);
  span.SetAttribute("key_bool", true);

  span.AddEvent("test_event");
  span.SetStatus(absl::OkStatus());
  span.SetStatus(absl::InvalidArgumentError("invalid argument"));
  span.End();
}

TEST(NoopTracerTest, StartSpanReturnsNonNullNoopSpan) {
  NoopTracer tracer;
  StartSpanOptions options;

  std::unique_ptr<Span> span = tracer.StartSpan("test_span", options);
  ASSERT_NE(span, nullptr);

  span->SetAttribute("key", int64_t{100});
  span->AddEvent("event");
  span->SetStatus(absl::OkStatus());
  span->End();
}

TEST(NoopTracerTest, IntegrationWithScopedSpan) {
  NoopTracer tracer;
  {
    ScopedSpan scoped_span(tracer.StartSpan("scoped_op", {}));
    ASSERT_NE(scoped_span.get(), nullptr);
    scoped_span->SetAttribute("attr", std::string("val"));
    scoped_span.SetStatus(absl::OkStatus());
  }
}

}  // namespace
}  // namespace credentio_tracing
