// 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.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef TINK_KEYSET_MANAGER_H_
#define TINK_KEYSET_MANAGER_H_

#include "absl/base/thread_annotations.h"
#include "absl/synchronization/mutex.h"
#include "tink/util/status.h"
#include "tink/util/statusor.h"
#include "proto/tink.pb.h"

namespace crypto {
namespace tink {

class KeysetHandle;

// KeysetManager provides convenience methods for creation of Keysets, and for
// rotating, disabling, enabling, or destroying keys.
// An instance of this class takes care of a single Keyset, that can be
// accessed via GetKeysetHandle()-method.
class KeysetManager {
 public:
  // Constructs a KeysetManager with an empty Keyset.
  KeysetManager() {}

  // Creates a new KeysetManager that contains a Keyset with a single key
  // generated freshly according the specification in 'key_template'.
  static crypto::tink::util::StatusOr<std::unique_ptr<KeysetManager>> New(
      const google::crypto::tink::KeyTemplate& key_template);

  // Creates a new KeysetManager that contains a Keyset cloned from
  // the given 'keyset_handle'.
  static crypto::tink::util::StatusOr<std::unique_ptr<KeysetManager>> New(
      const KeysetHandle& keyset_handle);

  // Adds to the managed keyset a fresh key generated according to
  // 'keyset_template' and returns the key_id of the added key.
  // The added key has status 'ENABLED'.
  crypto::tink::util::StatusOr<uint32_t> Add(
      const google::crypto::tink::KeyTemplate& key_template)
      LOCKS_EXCLUDED(keyset_mutex_);

  // Adds to the managed keyset a fresh key generated according to
  // 'keyset_template', sets the new key as the primary,
  // and returns the key_id of the added key.
  // The key that was primary prior to rotation remains 'ENABLED'.
  crypto::tink::util::StatusOr<uint32_t> Rotate(
      const google::crypto::tink::KeyTemplate& key_template)
      LOCKS_EXCLUDED(keyset_mutex_);

  // Sets the status of the specified key to 'ENABLED'.
  // Succeeds only if before the call the specified key
  // has status 'DISABLED' or 'ENABLED'.
  crypto::tink::util::Status Enable(uint32_t key_id)
      LOCKS_EXCLUDED(keyset_mutex_);

  // Sets the status of the specified key to 'DISABLED'.
  // Succeeds only if before the call the specified key
  // is not primary and has status 'DISABLED' or 'ENABLED'.
  crypto::tink::util::Status Disable(uint32_t key_id)
      LOCKS_EXCLUDED(keyset_mutex_);

  // Sets the status of the specified key to 'DESTROYED',
  // and removes the corresponding key material, if any.
  // Succeeds only if before the call the specified key
  // is not primary and has status 'DISABLED', or 'ENABLED',
  // or 'DESTROYED'.
  crypto::tink::util::Status Destroy(uint32_t key_id)
      LOCKS_EXCLUDED(keyset_mutex_);

  // Removes the specifed key from the managed keyset.
  // Succeeds only if the specified key is not primary.
  // After deletion the keyset contains one key fewer.
  crypto::tink::util::Status Delete(uint32_t key_id)
      LOCKS_EXCLUDED(keyset_mutex_);

  // Sets the specified key as the primary.
  // Succeeds only if the specified key is 'ENABLED'.
  crypto::tink::util::Status SetPrimary(uint32_t key_id)
      LOCKS_EXCLUDED(keyset_mutex_);

  // Returns the count of all keys in the keyset.
  int KeyCount() const;

  // Returns a handle with a copy of the managed keyset.
  std::unique_ptr<KeysetHandle> GetKeysetHandle() LOCKS_EXCLUDED(keyset_mutex_);

 private:
  crypto::tink::util::StatusOr<uint32_t> Add(
      const google::crypto::tink::KeyTemplate& key_template, bool as_primary)
      LOCKS_EXCLUDED(keyset_mutex_);

  mutable absl::Mutex keyset_mutex_;
  google::crypto::tink::Keyset keyset_ GUARDED_BY(keyset_mutex_);
};

}  // namespace tink
}  // namespace crypto

#endif  // TINK_KEYSET_MANAGER_H_
