// 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_CORE_KEY_MANAGER_IMPL_H_
#define TINK_CORE_KEY_MANAGER_IMPL_H_

#include "tink/core/key_manager_base.h"
#include "tink/core/key_type_manager.h"
#include "tink/key_manager.h"
#include "tink/util/status.h"
#include "proto/tink.pb.h"

namespace crypto {
namespace tink {
namespace internal {

// Template declaration of the class "KeyFactoryImpl" with a single template
// argument. We first declare it, then later give two "partial template
// specializations". This will imply that the KeyFactoryImpl can only be
// instantiated with arguments of the form KeyTypeManager<...>.
template <class KeyTypeManager>
class KeyFactoryImpl;

// First partial template specialization for KeyFactoryImpl: the given
// KeyTypeManager is of the form KeyTypeManager<KeyProto,
// KeyFormatProto, List<Primitives...>>.
template <class KeyProto, class KeyFormatProto, class... Primitives>
class KeyFactoryImpl<
    KeyTypeManager<KeyProto, KeyFormatProto, List<Primitives...>>>
    : public KeyFactory {
 public:
  explicit KeyFactoryImpl(KeyTypeManager<KeyProto, KeyFormatProto,
                                         List<Primitives...>>* key_type_manager)
      : key_type_manager_(key_type_manager) {}

  crypto::tink::util::StatusOr<std::unique_ptr<portable_proto::MessageLite>>
  NewKey(const portable_proto::MessageLite& key_format) const override {
    if (key_format.GetTypeName() != KeyFormatProto().GetTypeName()) {
      return crypto::tink::util::Status(
          util::error::INVALID_ARGUMENT,
          absl::StrCat("Key format proto '", key_format.GetTypeName(),
                       "' is not supported by this manager."));
    }
    auto validation = key_type_manager_->ValidateKeyFormat(
        static_cast<const KeyFormatProto&>(key_format));
    if (!validation.ok()) {
      return validation;
    }
    crypto::tink::util::StatusOr<KeyProto> new_key_result =
        key_type_manager_->CreateKey(
            static_cast<const KeyFormatProto&>(key_format));
    if (!new_key_result.ok()) return new_key_result.status();
    return absl::implicit_cast<std::unique_ptr<portable_proto::MessageLite>>(
        absl::make_unique<KeyProto>(std::move(new_key_result.ValueOrDie())));
  }

  crypto::tink::util::StatusOr<std::unique_ptr<portable_proto::MessageLite>>
  NewKey(absl::string_view serialized_key_format) const override {
    KeyFormatProto key_format;
    if (!key_format.ParseFromString(std::string(serialized_key_format))) {
      return crypto::tink::util::Status(
          util::error::INVALID_ARGUMENT,
          absl::StrCat("Could not parse the passed string as proto '",
                       KeyFormatProto().GetTypeName(), "'."));
    }
    auto validation = key_type_manager_->ValidateKeyFormat(key_format);
    if (!validation.ok()) {
      return validation;
    }
    return NewKey(static_cast<const portable_proto::MessageLite&>(key_format));
  }

  crypto::tink::util::StatusOr<std::unique_ptr<google::crypto::tink::KeyData>>
  NewKeyData(absl::string_view serialized_key_format) const override {
    auto new_key_result = NewKey(serialized_key_format);
    if (!new_key_result.ok()) return new_key_result.status();
    auto new_key = static_cast<const KeyProto&>(*(new_key_result.ValueOrDie()));
    auto key_data = absl::make_unique<google::crypto::tink::KeyData>();
    key_data->set_type_url(
        absl::StrCat(kTypeGoogleapisCom, KeyProto().GetTypeName()));
    key_data->set_value(new_key.SerializeAsString());
    key_data->set_key_material_type(key_type_manager_->key_material_type());
    return std::move(key_data);
  }

 private:
  KeyTypeManager<KeyProto, KeyFormatProto, List<Primitives...>>*
      key_type_manager_;
};

// Second partial template specialization for KeyFactoryImpl: the given
// KeyTypeManager is of the form KeyTypeManager<KeyProto, void,
// List<Primitives...>>.
template <class KeyProto, class... Primitives>
class KeyFactoryImpl<KeyTypeManager<KeyProto, void, List<Primitives...>>>
    : public KeyFactory {
 public:
  // We don't need the KeyTypeManager, but this is called from a template,
  // so the easiest way to ignore the argument is to provide a constructor which
  // ignores the argument.
  explicit KeyFactoryImpl(
      KeyTypeManager<KeyProto, void, List<Primitives...>>* key_type_manager) {}

  crypto::tink::util::StatusOr<std::unique_ptr<portable_proto::MessageLite>>
  NewKey(const portable_proto::MessageLite& key_format) const override {
    return util::Status(
        util::error::UNIMPLEMENTED,
        "Creating new keys is not supported for this key manager.");
  }

  crypto::tink::util::StatusOr<std::unique_ptr<portable_proto::MessageLite>>
  NewKey(absl::string_view serialized_key_format) const override {
    return util::Status(
        util::error::UNIMPLEMENTED,
        "Creating new keys is not supported for this key manager.");
  }

  crypto::tink::util::StatusOr<std::unique_ptr<google::crypto::tink::KeyData>>
  NewKeyData(absl::string_view serialized_key_format) const override {
    return util::Status(
        util::error::UNIMPLEMENTED,
        "Creating new keys is not supported for this key manager.");
  }
};

// Template declaration of the class "KeyManagerImpl" with two template
// arguments. There is only one specialization which is defined, namely when
// the KeyTypeManager argument is of the form KeyTypeManager<KeyProto,
// KeyFormatProto, List<Primitives...>>. We don't provide a
// specialization for the case KeyFormatProto = void, so the compiler will pick
// this instantiation in this case.
template <class Primitive, class KeyTypeManager>
class KeyManagerImpl;

// The first template argument to the KeyManagerImpl is the primitive for which
// we should generate a KeyManager. The second is the KeyTypeManager, which
// takes itself template arguments. The list of the Primitives there must
// contain the first Primitive argument (otherwise there will be failures at
// runtime).
template <class Primitive, class KeyProto, class KeyFormatProto,
          class... Primitives>
class KeyManagerImpl<
    Primitive, KeyTypeManager<KeyProto, KeyFormatProto, List<Primitives...>>>
    : public KeyManager<Primitive> {
 public:
  explicit KeyManagerImpl(KeyTypeManager<KeyProto, KeyFormatProto,
                                         List<Primitives...>>* key_type_manager)
      : key_type_manager_(key_type_manager),
        key_factory_(
            absl::make_unique<KeyFactoryImpl<
                KeyTypeManager<KeyProto, KeyFormatProto, List<Primitives...>>>>(
                key_type_manager_)) {}

  // Constructs an instance of Primitive for the given 'key_data'.
  crypto::tink::util::StatusOr<std::unique_ptr<Primitive>> GetPrimitive(
      const google::crypto::tink::KeyData& key_data) const override {
    if (!this->DoesSupport(key_data.type_url())) {
      return ToStatusF(util::error::INVALID_ARGUMENT,
                       "Key type '%s' is not supported by this manager.",
                       key_data.type_url().c_str());
    }
    KeyProto key_proto;
    if (!key_proto.ParseFromString(key_data.value())) {
      return ToStatusF(util::error::INVALID_ARGUMENT,
                       "Could not parse key_data.value as key type '%s'.",
                       key_data.type_url().c_str());
    }
    auto validation = key_type_manager_->ValidateKey(key_proto);
    if (!validation.ok()) {
      return validation;
    }
    return key_type_manager_->template GetPrimitive<Primitive>(key_proto);
  }

  crypto::tink::util::StatusOr<std::unique_ptr<Primitive>> GetPrimitive(
      const portable_proto::MessageLite& key) const override {
    std::string key_type = absl::StrCat(kTypeGoogleapisCom, key.GetTypeName());
    if (!this->DoesSupport(key_type)) {
      return ToStatusF(util::error::INVALID_ARGUMENT,
                       "Key type '%s' is not supported by this manager.",
                       key_type.c_str());
    }
    const KeyProto& key_proto = static_cast<const KeyProto&>(key);
    auto validation = key_type_manager_->ValidateKey(key_proto);
    if (!validation.ok()) {
      return validation;
    }
    return key_type_manager_->template GetPrimitive<Primitive>(key_proto);
  }

  uint32_t get_version() const override {
    return key_type_manager_->get_version();
  }

  const std::string& get_key_type() const override {
    return key_type_manager_->get_key_type();
  }

  const KeyFactory& get_key_factory() const override {
    return *key_factory_;
  }

 private:
  KeyTypeManager<KeyProto, KeyFormatProto, List<Primitives...>>*
      key_type_manager_;
  std::unique_ptr<KeyFactory> key_factory_;
};

// Helper function to create a KeyManager<Primitive> from a KeyTypeManager.
// Using this, all template arguments except the first one can be infered.
// Example:
//   std::unique_ptr<KeyManager<Aead>> km =
//     MakeKeyManager<Aead>(my_key_type_manager.get());
template <class Primitive, class KeyProto, class KeyFormatProto,
          class... Primitives>
std::unique_ptr<KeyManager<Primitive>> MakeKeyManager(
    KeyTypeManager<KeyProto, KeyFormatProto, List<Primitives...>>*
        key_type_manager) {
  return absl::make_unique<
      KeyManagerImpl<Primitive, KeyTypeManager<KeyProto, KeyFormatProto,
                                               List<Primitives...>>>>(
      key_type_manager);
}

}  // namespace internal
}  // namespace tink
}  // namespace crypto

#endif  // TINK_CORE_KEY_MANAGER_IMPL_H_
