
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * 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
 *
 *      http://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 <cassert>

#include "chre/util/non_copyable.h"
#include "chre/util/optional.h"

using chre::Optional;

class DestructorTestingObject {
 public:
  ~DestructorTestingObject() {
    if (valueToFlipWhenDestruct != nullptr) {
      *valueToFlipWhenDestruct = !*valueToFlipWhenDestruct;
    }
  }

  void setValueToFlipWhenDestruct(bool *value) {
    valueToFlipWhenDestruct = value;
  }

 private:
  bool *valueToFlipWhenDestruct = nullptr;
};

TEST(Optional, ShouldDestructContainedObject) {
  bool destructed = false;
  {
    Optional<DestructorTestingObject> object(DestructorTestingObject{});
    object.value().setValueToFlipWhenDestruct(&destructed);
  }
  EXPECT_TRUE(destructed);
}

TEST(Optional, NoValueByDefault) {
  Optional<int> myInt;
  EXPECT_FALSE(myInt.has_value());
}

TEST(Optional, NonDefaultValueByDefault) {
  Optional<int> myInt(0x1337);
  EXPECT_TRUE(myInt.has_value());
  EXPECT_EQ(*myInt, 0x1337);
}

TEST(Optional, NonDefaultMovedValueByDefault) {
  Optional<int> myInt(std::move(0x1337));
  EXPECT_TRUE(myInt.has_value());
  EXPECT_EQ(*myInt, 0x1337);
}

TEST(Optional, CopyConstruct) {
  Optional<int> myInt(0x1337);
  Optional<int> myNewInt(myInt);
  EXPECT_TRUE(myNewInt.has_value());
  EXPECT_EQ(*myNewInt, 0x1337);
}

TEST(Optional, CopyConstructConst) {
  const Optional<int> myInt(0x1337);
  Optional<int> myNewInt(myInt);
  EXPECT_TRUE(myNewInt.has_value());
  EXPECT_EQ(*myNewInt, 0x1337);
}

TEST(Optional, CopyAssignAndRead) {
  Optional<int> myInt;
  EXPECT_FALSE(myInt.has_value());
  myInt = 0x1337;
  EXPECT_EQ(*myInt, 0x1337);
  EXPECT_TRUE(myInt.has_value());
  myInt.reset();
  EXPECT_FALSE(myInt.has_value());
}

TEST(Optional, MoveAssignAndRead) {
  Optional<int> myInt;
  EXPECT_FALSE(myInt.has_value());
  myInt = std::move(0xcafe);
  EXPECT_TRUE(myInt.has_value());
  EXPECT_EQ(*myInt, 0xcafe);
}

TEST(Optional, OptionalMoveAssignAndRead) {
  Optional<int> myInt(0x1337);
  Optional<int> myMovedInt;
  EXPECT_FALSE(myMovedInt.has_value());
  myMovedInt = std::move(myInt);
  EXPECT_TRUE(myInt.has_value());
  EXPECT_TRUE(myMovedInt.has_value());
  EXPECT_EQ(*myMovedInt, 0x1337);
}

TEST(Optional, OptionalCopyAssignAndRead) {
  Optional<int> myInt(0x1337);
  Optional<int> myCopiedInt;
  EXPECT_FALSE(myCopiedInt.has_value());
  myCopiedInt = myInt;
  EXPECT_TRUE(myInt.has_value());
  EXPECT_TRUE(myCopiedInt.has_value());
  EXPECT_EQ(*myInt, 0x1337);
  EXPECT_EQ(*myCopiedInt, 0x1337);
}

static constexpr int kInvalidValue = -1;

class MovableButNonCopyable : public chre::NonCopyable {
 public:
  MovableButNonCopyable() = default;
  MovableButNonCopyable(int value) : mValue(value) {}
  MovableButNonCopyable(MovableButNonCopyable &&other) {
    mValue = other.mValue;
    other.mValue = kInvalidValue;
  }

  MovableButNonCopyable &operator=(MovableButNonCopyable &&other) {
    assert(mMagic == kConstructedMagic);
    mValue = other.mValue;
    other.mValue = kInvalidValue;
    return *this;
  }

  ~MovableButNonCopyable() {
    mMagic = kUninitializedMagic;
    mValue = kUninitializedMagic;
  }

  int getValue() const {
    return mValue;
  }

 private:
  static constexpr int kConstructedMagic = 0xfeedc0fe;
  static constexpr int kUninitializedMagic = 0xdeadbeef;

  int mMagic = kConstructedMagic;
  int mValue = kInvalidValue;
};

TEST(Optional, UninitializedAssignment) {
  constexpr int kValue1 = 0xd00d;
  constexpr int kValue2 = 0xcafe;
  MovableButNonCopyable transferee1(kValue1);
  MovableButNonCopyable transferee2(kValue2);

  Optional<MovableButNonCopyable> container;
  EXPECT_FALSE(container.has_value());

  container = std::move(transferee1);
  EXPECT_TRUE(container.has_value());
  EXPECT_EQ(container->getValue(), kValue1);
  EXPECT_EQ(transferee1.getValue(), kInvalidValue);

  container.reset();
  EXPECT_FALSE(container.has_value());

  container = std::move(transferee2);
  EXPECT_TRUE(container.has_value());
  EXPECT_EQ(container->getValue(), kValue2);
  EXPECT_EQ(transferee2.getValue(), kInvalidValue);
}

// TODO: should add some tests to cover the possible assignment outcomes between
// two Optional instances (e.g. assign one w/o value to one w/value, etc)
