// Copyright 2017 Google Inc.
//
// 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/keyset_manager.h"

#include "gtest/gtest.h"
#include "tink/aead/aead_config.h"
#include "tink/aead/aes_gcm_key_manager.h"
#include "tink/config.h"
#include "tink/keyset_handle.h"
#include "tink/util/test_keyset_handle.h"
#include "proto/aes_gcm.pb.h"
#include "proto/tink.pb.h"

using crypto::tink::TestKeysetHandle;

using google::crypto::tink::AesGcmKeyFormat;
using google::crypto::tink::KeyData;
using google::crypto::tink::KeyStatusType;
using google::crypto::tink::KeyTemplate;
using google::crypto::tink::OutputPrefixType;

namespace crypto {
namespace tink {

class KeysetManagerTest : public ::testing::Test {
 protected:
  void SetUp() override {
    auto status = AeadConfig::Register();
    ASSERT_TRUE(status.ok()) << status;
  }
  void TearDown() override {}
};

TEST_F(KeysetManagerTest, testBasicOperations) {
  AesGcmKeyFormat key_format;
  key_format.set_key_size(16);
  KeyTemplate key_template;
  key_template.set_type_url(AesGcmKeyManager::static_key_type());
  key_template.set_output_prefix_type(OutputPrefixType::TINK);
  key_template.set_value(key_format.SerializeAsString());

  // Create a keyset manager with a single key.
  auto new_result = KeysetManager::New(key_template);
  EXPECT_TRUE(new_result.ok()) << new_result.status();
  auto keyset_manager = std::move(new_result.ValueOrDie());
  EXPECT_EQ(1, keyset_manager->KeyCount());

  // Verify the keyset.
  auto keyset =
      TestKeysetHandle::GetKeyset(*(keyset_manager->GetKeysetHandle()));
  EXPECT_EQ(1, keyset.key().size());
  auto key_id_0 = keyset.key(0).key_id();
  EXPECT_EQ(key_id_0, keyset.primary_key_id());
  EXPECT_EQ(KeyStatusType::ENABLED, keyset.key(0).status());
  EXPECT_EQ(OutputPrefixType::TINK, keyset.key(0).output_prefix_type());
  EXPECT_EQ(AesGcmKeyManager::static_key_type(),
            keyset.key(0).key_data().type_url());
  EXPECT_EQ(KeyData::SYMMETRIC, keyset.key(0).key_data().key_material_type());

  // Add another key.
  key_template.set_output_prefix_type(OutputPrefixType::RAW);
  auto add_result = keyset_manager->Add(key_template);
  EXPECT_TRUE(add_result.ok()) << add_result.status();
  EXPECT_EQ(2, keyset_manager->KeyCount());
  auto key_id_1 = add_result.ValueOrDie();
  keyset = TestKeysetHandle::GetKeyset(*(keyset_manager->GetKeysetHandle()));
  EXPECT_EQ(2, keyset.key().size());
  EXPECT_EQ(key_id_0, keyset.primary_key_id());
  EXPECT_FALSE(keyset.key(0).key_data().value() ==
               keyset.key(1).key_data().value());
  EXPECT_EQ(KeyStatusType::ENABLED, keyset.key(1).status());
  EXPECT_EQ(OutputPrefixType::RAW, keyset.key(1).output_prefix_type());
  EXPECT_EQ(AesGcmKeyManager::static_key_type(),
            keyset.key(1).key_data().type_url());
  EXPECT_EQ(KeyData::SYMMETRIC, keyset.key(1).key_data().key_material_type());

  // And another one, via rotation.
  key_template.set_output_prefix_type(OutputPrefixType::LEGACY);
  auto rotate_result = keyset_manager->Rotate(key_template);
  EXPECT_TRUE(rotate_result.ok()) << add_result.status();
  EXPECT_EQ(3, keyset_manager->KeyCount());
  auto key_id_2 = rotate_result.ValueOrDie();
  keyset = TestKeysetHandle::GetKeyset(*(keyset_manager->GetKeysetHandle()));
  EXPECT_EQ(3, keyset.key().size());
  EXPECT_EQ(key_id_2, keyset.primary_key_id());
  EXPECT_FALSE(keyset.key(0).key_data().value() ==
               keyset.key(2).key_data().value());
  EXPECT_FALSE(keyset.key(1).key_data().value() ==
               keyset.key(2).key_data().value());
  EXPECT_EQ(KeyStatusType::ENABLED, keyset.key(2).status());
  EXPECT_EQ(OutputPrefixType::LEGACY, keyset.key(2).output_prefix_type());
  EXPECT_EQ(AesGcmKeyManager::static_key_type(),
            keyset.key(2).key_data().type_url());
  EXPECT_EQ(KeyData::SYMMETRIC, keyset.key(2).key_data().key_material_type());

  // Change the primary.
  auto status = keyset_manager->SetPrimary(key_id_1);
  EXPECT_TRUE(status.ok()) << status;
  keyset = TestKeysetHandle::GetKeyset(*(keyset_manager->GetKeysetHandle()));
  EXPECT_EQ(3, keyset.key().size());
  EXPECT_EQ(3, keyset_manager->KeyCount());
  EXPECT_EQ(key_id_1, keyset.primary_key_id());

  // Clone a keyset via the manager, and check equality.
  auto keyset_manager_2 = std::move(
      KeysetManager::New(*keyset_manager->GetKeysetHandle()).ValueOrDie());
  auto keyset_2 =
      TestKeysetHandle::GetKeyset(*(keyset_manager_2->GetKeysetHandle()));
  EXPECT_EQ(keyset.SerializeAsString(), keyset_2.SerializeAsString());

  // Disable a key, and try to set it as primary.
  EXPECT_EQ(KeyStatusType::ENABLED, keyset.key(2).status());
  status = keyset_manager->Disable(key_id_2);
  EXPECT_TRUE(status.ok()) << status;
  EXPECT_EQ(3, keyset_manager->KeyCount());
  keyset = TestKeysetHandle::GetKeyset(*(keyset_manager->GetKeysetHandle()));
  EXPECT_EQ(KeyStatusType::DISABLED, keyset.key(2).status());

  status = keyset_manager->SetPrimary(key_id_2);
  EXPECT_FALSE(status.ok());
  EXPECT_EQ(util::error::INVALID_ARGUMENT, status.error_code());
  EXPECT_PRED_FORMAT2(testing::IsSubstring, "must be ENABLED",
                      status.error_message());
  keyset = TestKeysetHandle::GetKeyset(*(keyset_manager->GetKeysetHandle()));
  EXPECT_EQ(key_id_1, keyset.primary_key_id());

  // Enable ENABLED key, disable a DISABLED one.
  EXPECT_EQ(KeyStatusType::ENABLED, keyset.key(1).status());
  status = keyset_manager->Enable(key_id_1);
  EXPECT_TRUE(status.ok()) << status;
  keyset = TestKeysetHandle::GetKeyset(*(keyset_manager->GetKeysetHandle()));
  EXPECT_EQ(KeyStatusType::ENABLED, keyset.key(1).status());

  EXPECT_EQ(KeyStatusType::DISABLED, keyset.key(2).status());
  status = keyset_manager->Disable(key_id_2);
  EXPECT_TRUE(status.ok()) << status;
  keyset = TestKeysetHandle::GetKeyset(*(keyset_manager->GetKeysetHandle()));
  EXPECT_EQ(KeyStatusType::DISABLED, keyset.key(2).status());

  // Enable the disabled key, then destroy it, and try to re-enable.
  EXPECT_EQ(KeyStatusType::DISABLED, keyset.key(2).status());
  status = keyset_manager->Enable(key_id_2);
  EXPECT_TRUE(status.ok()) << status;
  keyset = TestKeysetHandle::GetKeyset(*(keyset_manager->GetKeysetHandle()));
  EXPECT_EQ(KeyStatusType::ENABLED, keyset.key(2).status());
  EXPECT_TRUE(keyset.key(2).has_key_data());

  status = keyset_manager->Destroy(key_id_2);
  EXPECT_TRUE(status.ok()) << status;
  EXPECT_EQ(3, keyset_manager->KeyCount());
  keyset = TestKeysetHandle::GetKeyset(*(keyset_manager->GetKeysetHandle()));
  EXPECT_EQ(KeyStatusType::DESTROYED, keyset.key(2).status());
  EXPECT_FALSE(keyset.key(2).has_key_data());

  status = keyset_manager->Enable(key_id_2);
  EXPECT_FALSE(status.ok());
  EXPECT_EQ(util::error::INVALID_ARGUMENT, status.error_code());
  EXPECT_PRED_FORMAT2(testing::IsSubstring, "Cannot enable",
                      status.error_message());
  keyset = TestKeysetHandle::GetKeyset(*(keyset_manager->GetKeysetHandle()));
  EXPECT_EQ(KeyStatusType::DESTROYED, keyset.key(2).status());
  EXPECT_EQ(key_id_1, keyset.primary_key_id());

  // Delete the destroyed key, then try to destroy and delete it again.
  status = keyset_manager->Delete(key_id_2);
  EXPECT_TRUE(status.ok()) << status;
  EXPECT_EQ(2, keyset_manager->KeyCount());
  keyset = TestKeysetHandle::GetKeyset(*(keyset_manager->GetKeysetHandle()));

  EXPECT_EQ(2, keyset.key().size());

  status = keyset_manager->Destroy(key_id_2);
  EXPECT_EQ(util::error::NOT_FOUND, status.error_code());
  EXPECT_PRED_FORMAT2(testing::IsSubstring, "No key with key_id",
                      status.error_message());

  status = keyset_manager->Delete(key_id_2);
  EXPECT_EQ(util::error::NOT_FOUND, status.error_code());
  EXPECT_PRED_FORMAT2(testing::IsSubstring, "No key with key_id",
                      status.error_message());

  // Try disabling/destroying/deleting the primary key.
  keyset = TestKeysetHandle::GetKeyset(*(keyset_manager->GetKeysetHandle()));

  EXPECT_EQ(key_id_1, keyset.primary_key_id());

  status = keyset_manager->Disable(key_id_1);
  EXPECT_EQ(util::error::INVALID_ARGUMENT, status.error_code());
  EXPECT_PRED_FORMAT2(testing::IsSubstring, "Cannot disable primary",
                      status.error_message());

  status = keyset_manager->Destroy(key_id_1);
  EXPECT_EQ(util::error::INVALID_ARGUMENT, status.error_code());
  EXPECT_PRED_FORMAT2(testing::IsSubstring, "Cannot destroy primary",
                      status.error_message());

  status = keyset_manager->Delete(key_id_1);
  EXPECT_EQ(util::error::INVALID_ARGUMENT, status.error_code());
  EXPECT_PRED_FORMAT2(testing::IsSubstring, "Cannot delete primary",
                      status.error_message());

  keyset = TestKeysetHandle::GetKeyset(*(keyset_manager->GetKeysetHandle()));
  EXPECT_EQ(key_id_1, keyset.primary_key_id());

  // Delete the first key, then try to set it as primary.
  status = keyset_manager->Delete(key_id_0);
  EXPECT_TRUE(status.ok()) << status;
  keyset = TestKeysetHandle::GetKeyset(*(keyset_manager->GetKeysetHandle()));
  EXPECT_EQ(1, keyset.key().size());
  EXPECT_EQ(key_id_1, keyset.key(0).key_id());

  status = keyset_manager->SetPrimary(key_id_0);
  EXPECT_FALSE(status.ok());
  EXPECT_EQ(util::error::NOT_FOUND, status.error_code());
  EXPECT_PRED_FORMAT2(testing::IsSubstring, "No key with key_id",
                      status.error_message());
  EXPECT_EQ(1, keyset_manager->KeyCount());
}

}  // namespace tink
}  // namespace crypto
