// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/lib/util/encrypted_message_util.h"

#include <utility>
#include <vector>

#include "google/protobuf/message_lite.h"
#include "src/lib/util/not_null.h"
#include "src/logging.h"
#include "src/pb/encrypted_message.pb.h"
#include "src/pb/key.pb.h"
#include "src/public/lib/status.h"
#include "src/public/lib/status_codes.h"
#include "src/tracing.h"

#if TQ_COBALT_USE_TINK
#include "src/lib/util/hybrid_tink_encrypted_message_maker.h"
#endif

namespace cobalt::util {

namespace {

#if TQ_COBALT_USE_TINK
constexpr char kShufflerContextInfo[] = "cobalt-1.0-shuffler";
constexpr char kAnalyzerContextInfo[] = "cobalt-1.0-analyzer";
#endif

// Parse and validate a serialized CobaltEncryptionKey.
lib::statusor::StatusOr<cobalt::CobaltEncryptionKey> ParseCobaltEncryptionKey(
    const std::string& cobalt_encryption_key_bytes) {
  cobalt::CobaltEncryptionKey cobalt_encryption_key;
  if (!cobalt_encryption_key.ParseFromString(cobalt_encryption_key_bytes)) {
    return Status(StatusCode::INVALID_ARGUMENT,
                  "EncryptedMessageMaker: Invalid Cobalt encryption key.");
  }

  if (cobalt_encryption_key.key_index() == 0) {
    return Status(StatusCode::INVALID_ARGUMENT,
                  "EncryptedMessageMaker: Invalid Cobalt key_index: 0.");
  }

  if (cobalt_encryption_key.purpose() != cobalt::CobaltEncryptionKey::SHUFFLER &&
      cobalt_encryption_key.purpose() != cobalt::CobaltEncryptionKey::ANALYZER) {
    return Status(StatusCode::INVALID_ARGUMENT,
                  "EncryptedMessageMaker: Invalid Cobalt key purpose.");
  }

  return cobalt_encryption_key;
}
}  // namespace

util::NotNullUniquePtr<EncryptedMessageMaker> EncryptedMessageMaker::MakeUnencrypted() {
  VLOG(5) << "WARNING: Cobalt data will not be encrypted!";
  return util::MakeNotNullUniquePtr<UnencryptedMessageMaker>();
}

lib::statusor::StatusOr<util::NotNullUniquePtr<EncryptedMessageMaker>>
EncryptedMessageMaker::MakeForEnvelopes(const std::string& cobalt_encryption_key_bytes) {
  auto cobalt_encryption_key_or_result = ParseCobaltEncryptionKey(cobalt_encryption_key_bytes);
  if (!cobalt_encryption_key_or_result.ok()) {
    return cobalt_encryption_key_or_result.status();
  }
  auto cobalt_encryption_key = cobalt_encryption_key_or_result.value();

  if (cobalt_encryption_key.purpose() != cobalt::CobaltEncryptionKey::SHUFFLER) {
    return Status(StatusCode::INVALID_ARGUMENT, "EncryptedMessageMaker: Expected a shuffler key.");
  }

#if TQ_COBALT_USE_TINK
  return MakeHybridTinkEncryptedMessageMaker(cobalt_encryption_key.serialized_key(),
                                             kShufflerContextInfo,
                                             cobalt_encryption_key.key_index());
#else
  return Status(StatusCode::UNIMPLEMENTED, "EncryptedMessageMaker: Cobalt was built without Tink.");
#endif
}

lib::statusor::StatusOr<util::NotNullUniquePtr<EncryptedMessageMaker>>
EncryptedMessageMaker::MakeForObservations(const std::string& cobalt_encryption_key_bytes) {
  auto cobalt_encryption_key_or_result = ParseCobaltEncryptionKey(cobalt_encryption_key_bytes);
  if (!cobalt_encryption_key_or_result.ok()) {
    return cobalt_encryption_key_or_result.status();
  }
  auto cobalt_encryption_key = cobalt_encryption_key_or_result.value();

  if (cobalt_encryption_key.purpose() != cobalt::CobaltEncryptionKey::ANALYZER) {
    return Status(StatusCode::INVALID_ARGUMENT, "EncryptedMessageMaker: Expected an analyzer key.");
  }

#if TQ_COBALT_USE_TINK
  return MakeHybridTinkEncryptedMessageMaker(cobalt_encryption_key.serialized_key(),
                                             kAnalyzerContextInfo,
                                             cobalt_encryption_key.key_index());
#else
  return Status(StatusCode::UNIMPLEMENTED, "EncryptedMessageMaker: Cobalt was built without Tink.");
#endif
}

bool UnencryptedMessageMaker::Encrypt(const google::protobuf::MessageLite& message,
                                      EncryptedMessage* encrypted_message) const {
  TRACE_DURATION("cobalt_core", "UnencryptedMessageMaker::Encrypt");
  if (!encrypted_message) {
    return false;
  }
  std::string serialized_message;
  message.SerializeToString(&serialized_message);
  encrypted_message->set_ciphertext(serialized_message);
  VLOG(5) << "EncryptedMessage: encryption_scheme=NONE.";
  return true;
}

}  // namespace cobalt::util
