// Copyright 2022 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 "pw_toolchain/no_destructor.h"

#include "pw_assert/check.h"
#include "pw_unit_test/framework.h"

namespace pw {
namespace {

class HasADestructor {
 public:
  HasADestructor(bool& destructor_called_flag)
      : destructor_called_(destructor_called_flag) {
    destructor_called_ = false;
  }

  ~HasADestructor() { destructor_called_ = true; }

 private:
  bool& destructor_called_;
};

class CrashInDestructor {
 public:
  const CrashInDestructor* MyAddress() const { return this; }

  int some_value = 0;

 private:
  ~CrashInDestructor() { PW_CRASH("This destructor should never execute!"); }
};

class TrivialDestructor {
 public:
  TrivialDestructor(int initial_value) : value(initial_value) {}

  int value;
};

TEST(NoDestructor, ShouldNotCallDestructor) {
  bool destructor_called = false;

  {
    HasADestructor should_be_destroyed(destructor_called);
  }

  EXPECT_TRUE(destructor_called);

  {
    NoDestructor<HasADestructor> should_not_be_destroyed(destructor_called);
  }

  EXPECT_FALSE(destructor_called);
}

TEST(NoDestructor, MemberAccess) {
  NoDestructor<CrashInDestructor> no_destructor;

  no_destructor->some_value = 123;
  EXPECT_EQ(123, (*no_destructor).some_value);
  EXPECT_EQ(no_destructor.operator->(), no_destructor->MyAddress());
}

TEST(NoDestructor, TrivialDestructor) {
  NoDestructor<TrivialDestructor> no_destructor(555);

  EXPECT_EQ(no_destructor->value, 555);
  no_destructor->value = 123;
  EXPECT_EQ(no_destructor->value, 123);
}

TEST(NoDestructor, TrivialType) {
  NoDestructor<int> no_destructor;

  EXPECT_EQ(*no_destructor, 0);
  *no_destructor = 123;
  EXPECT_EQ(*no_destructor, 123);
}

TEST(NoDestructor, FunctionStatic) {
  static NoDestructor<CrashInDestructor> function_static_no_destructor;
}

NoDestructor<CrashInDestructor> global_no_destructor;

static_assert(!std::is_trivially_destructible<CrashInDestructor>::value,
              "Type should not be trivially destructible");
static_assert(
    std::is_trivially_destructible<NoDestructor<CrashInDestructor>>::value,
    "Wrapper should be trivially destructible");

}  // namespace
}  // namespace pw
