// Copyright 2019 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/streamingaead/decrypting_input_stream.h"

#include <algorithm>
#include <cstring>
#include <vector>

#include "absl/memory/memory.h"
#include "tink/input_stream.h"
#include "tink/primitive_set.h"
#include "tink/streaming_aead.h"
#include "tink/streamingaead/buffered_input_stream.h"
#include "tink/streamingaead/shared_input_stream.h"
#include "tink/util/errors.h"
#include "tink/util/status.h"
#include "tink/util/statusor.h"

namespace crypto {
namespace tink {
namespace streamingaead {

using crypto::tink::PrimitiveSet;
using crypto::tink::StreamingAead;
using util::Status;
using util::StatusOr;

// static
StatusOr<std::unique_ptr<InputStream>> DecryptingInputStream::New(
    std::shared_ptr<PrimitiveSet<StreamingAead>> primitives,
    std::unique_ptr<crypto::tink::InputStream> ciphertext_source,
    absl::string_view associated_data) {
  std::unique_ptr<DecryptingInputStream> dec_stream(
      new DecryptingInputStream());
  dec_stream->primitives_ = primitives;
  dec_stream->buffered_ct_source_ =
      std::make_shared<BufferedInputStream>(std::move(ciphertext_source));
  dec_stream->associated_data_ = std::string(associated_data);
  dec_stream->attempted_matching_ = false;
  dec_stream->matching_stream_ = nullptr;
  return {std::move(dec_stream)};
}

util::StatusOr<int> DecryptingInputStream::Next(const void** data) {
  if (matching_stream_ != nullptr) {
    return matching_stream_->Next(data);
  }
  if (attempted_matching_) {
    return Status(util::error::INVALID_ARGUMENT,
                  "Could not find a decrypter matching the ciphertext stream.");
  }
  // Matching has not been attempted yet, so try it now.
  attempted_matching_ = true;
  auto raw_primitives_result = primitives_->get_raw_primitives();
  if (!raw_primitives_result.ok()) {
    return Status(util::error::INTERNAL, "No RAW primitives found");
  }
  for (auto& primitive : *(raw_primitives_result.ValueOrDie())) {
    StreamingAead& streaming_aead = primitive->get_primitive();
    auto shared_ct = absl::make_unique<SharedInputStream>(
        buffered_ct_source_.get());
    auto decrypting_stream_result = streaming_aead.NewDecryptingStream(
        std::move(shared_ct), associated_data_);
    if (decrypting_stream_result.ok()) {
      auto next_result = decrypting_stream_result.ValueOrDie()->Next(data);
      if (next_result.status().error_code() == util::error::OUT_OF_RANGE ||
          next_result.ok()) {  // Found a match.
        buffered_ct_source_->DisableRewinding();
        matching_stream_ = std::move(decrypting_stream_result.ValueOrDie());
        return next_result;
      }
    }
    // Not a match, rewind and try the next primitive.
    Status s = buffered_ct_source_->Rewind();
    if (!s.ok()) {
      return s;
    }
  }
  return Status(util::error::INVALID_ARGUMENT,
                "Could not find a decrypter matching the ciphertext stream.");
}

void DecryptingInputStream::BackUp(int count) {
  if (matching_stream_ != nullptr) {
    matching_stream_->BackUp(count);
  }
}


int64_t DecryptingInputStream::Position() const {
  if (matching_stream_ != nullptr) {
    return matching_stream_->Position();
  }
  return 0;
}

}  // namespace streamingaead
}  // namespace tink
}  // namespace crypto
