// Copyright 2021 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
//
//     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 "tink/util/secret_proto.h"

#include <string>
#include <utility>

#include "google/protobuf/util/message_differencer.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/memory/memory.h"
#include "proto/test_proto.pb.h"

namespace crypto {
namespace tink {
namespace util {
namespace {

using ::google::crypto::tink::NestedTestProto;
using ::google::crypto::tink::TestProto;
using ::google::protobuf::util::MessageDifferencer;

template <typename T>
class SecretProtoTest : public testing::Test {};

using MyTypes = ::testing::Types<NestedTestProto, TestProto>;
TYPED_TEST_SUITE(SecretProtoTest, MyTypes);

template <typename T>
T CreateProto();

template <>
TestProto CreateProto<TestProto>() {
  TestProto proto;
  proto.set_num(123);
  proto.set_str("Single proto");
  return proto;
}

template <>
NestedTestProto CreateProto<NestedTestProto>() {
  NestedTestProto proto;
  proto.mutable_a()->set_num(12);
  proto.mutable_a()->set_str("A proto");
  proto.mutable_b()->set_num(14);
  proto.mutable_b()->set_str("B proto");
  proto.set_num(42);
  proto.set_str("Main proto");
  return proto;
}

TYPED_TEST(SecretProtoTest, DefaultConstructor) {
  SecretProto<TypeParam> s;
  EXPECT_TRUE(MessageDifferencer::Equals(*s, TypeParam()));
}

TYPED_TEST(SecretProtoTest, Constructor) {
  TypeParam proto = CreateProto<TypeParam>();
  SecretProto<TypeParam> s(proto);
  EXPECT_TRUE(MessageDifferencer::Equals(*s, proto));
}

TYPED_TEST(SecretProtoTest, CopyConstructor) {
  TypeParam proto = CreateProto<TypeParam>();
  SecretProto<TypeParam> s(proto);
  SecretProto<TypeParam> t(s);
  EXPECT_TRUE(MessageDifferencer::Equals(*s, proto));
  EXPECT_TRUE(MessageDifferencer::Equals(*t, proto));
}

TYPED_TEST(SecretProtoTest, SourceDestroyedAfterCopyConstructor) {
  TypeParam proto = CreateProto<TypeParam>();
  auto s = absl::make_unique<SecretProto<TypeParam>>(proto);
  SecretProto<TypeParam> t(*s);
  EXPECT_TRUE(MessageDifferencer::Equals(**s, proto));
  EXPECT_TRUE(MessageDifferencer::Equals(*t, proto));
  // Test with source destroyed after the copy
  s.reset();
  EXPECT_TRUE(MessageDifferencer::Equals(*t, proto));
}

TYPED_TEST(SecretProtoTest, AssignmentOperator) {
  TypeParam proto = CreateProto<TypeParam>();
  SecretProto<TypeParam> t;
  {
    SecretProto<TypeParam> s(proto);
    t = s;
    EXPECT_TRUE(MessageDifferencer::Equals(*s, proto));
    EXPECT_TRUE(MessageDifferencer::Equals(*t, proto));
  }
  // Test with source destroyed after the copy
  EXPECT_TRUE(MessageDifferencer::Equals(*t, proto));
}

TYPED_TEST(SecretProtoTest, MoveConstructor) {
  TypeParam proto = CreateProto<TypeParam>();
  SecretProto<TypeParam> s(proto);
  SecretProto<TypeParam> t(std::move(s));
  EXPECT_TRUE(MessageDifferencer::Equals(*t, proto));
  // NOLINTNEXTLINE: bugprone-use-after-move
  EXPECT_TRUE(MessageDifferencer::Equals(*s, TypeParam()) ||
              MessageDifferencer::Equals(*s, proto));
}

TYPED_TEST(SecretProtoTest, MoveAssignment) {
  TypeParam proto = CreateProto<TypeParam>();
  SecretProto<TypeParam> t;
  {
    SecretProto<TypeParam> s(proto);
    t = std::move(s);
    EXPECT_TRUE(MessageDifferencer::Equals(*t, proto));
    // NOLINTNEXTLINE: bugprone-use-after-move
    EXPECT_TRUE(MessageDifferencer::Equals(*s, TypeParam()) ||
                MessageDifferencer::Equals(*s, proto));
  }
  // Test with source destroyed after the move
  EXPECT_TRUE(MessageDifferencer::Equals(*t, proto));
}

TYPED_TEST(SecretProtoTest, FromSecretData) {
  TypeParam proto = CreateProto<TypeParam>();
  SecretData data;
  data.resize(proto.ByteSizeLong());
  ASSERT_TRUE(proto.SerializeToArray(data.data(), data.size()));
  StatusOr<SecretProto<TypeParam>> secret_proto =
      SecretProto<TypeParam>::ParseFromSecretData(data);
  ASSERT_TRUE(secret_proto.ok()) << secret_proto.status();
  EXPECT_TRUE(MessageDifferencer::Equals(**secret_proto, proto));
}

TYPED_TEST(SecretProtoTest, AsSecretData) {
  TypeParam proto = CreateProto<TypeParam>();
  std::string serialized = proto.SerializeAsString();
  SecretProto<TypeParam> secret_proto(proto);
  StatusOr<SecretData> secret_serialized = secret_proto.SerializeAsSecretData();
  ASSERT_TRUE(secret_serialized.ok()) << secret_serialized.status();
  EXPECT_EQ(serialized, SecretDataAsStringView(*secret_serialized));
}

}  // namespace
}  // namespace util
}  // namespace tink
}  // namespace crypto
