// Copyright 2019 Google LLC
//
// 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_OUTPUT_STREAM_WITH_RESULT_H_
#define TINK_OUTPUT_STREAM_WITH_RESULT_H_

#include <type_traits>

#include "tink/output_stream.h"
#include "tink/util/status.h"
#include "tink/util/statusor.h"

namespace crypto {
namespace tink {

// TODO(tholenst): Forward declare ExtractStatus function,
// as discussed in cl/269918867.
namespace internal {
// Closes the OutputStream and returns the status,
// for when ResultType is StatusOr<T>
template <class ResultType>
auto ExtractStatus(const ResultType& result)
    -> decltype(std::declval<ResultType>().status()) {
  return result.status();
}

// Closes the OutputStream and returns the status,
// for when ResultType is Status
template <class ResultType>
auto ExtractStatus(ResultType result) ->
    typename std::enable_if<std::is_same<ResultType, util::Status>::value,
                            util::Status>::type {
  return result;
}
}  // namespace internal

// An abstract OutputStream subclass that acts as a sink for data and returns a
// result after the stream has been closed.
// The result is only available if the stream was able to close with an ok
// status. Otherwise, the status of the GetResult call will be the same status
// as the Close call had. If Close is successful, GetResult is guaranteed to
// return a valid result.
// The return type of GetResult will be StatusOr<T>, except for T == Status, in
// which case the return type is Status.
template <class T>
class OutputStreamWithResult : public OutputStream {
 public:
  OutputStreamWithResult() : closed_(false) {}
  ~OutputStreamWithResult() override {}

  // The return type is StatusOr<T> if T != Status, and Status otherwise.
  using ResultType =
      typename std::conditional<std::is_same<T, util::Status>::value,
                                util::Status, util::StatusOr<T>>::type;

  // Get the result associated with this OutputStream. Can only be called on
  // closed streams, and will otherwise fail with FAILED_PRECONDITION as error
  // code.
  // If Close() returned an ok status, this method is guaranteed to contain a
  // valid result.
  // The return type is StatusOr<T> if T != Status, and Status otherwise.
  ResultType GetResult() {
    if (!closed_) {
      return util::Status(util::error::FAILED_PRECONDITION,
                          "Stream is not closed");
    }
    return result_;
  }

  // Close the stream and return the computed result. Equivalent to calling
  // Close() and GetResult() if Close() returned an OK status.
  // The return type is StatusOr<T> if T != Status, and Status otherwise.
  ResultType CloseAndGetResult() {
    util::Status closing_status = Close();
    if (!closing_status.ok()) {
      return closing_status;
    }
    return GetResult();
  }

  // Closes the OutputStream.
  util::Status Close() final {
    if (closed_) {
      return util::Status(util::error::FAILED_PRECONDITION, "Stream closed");
    }
    result_ = CloseStreamAndComputeResult();
    closed_ = true;

    return internal::ExtractStatus(result_);
  }

  // Getting the next OutputStream buffer. See OutputStream for detailed
  // description.
  crypto::tink::util::StatusOr<int> Next(void** data) final {
    if (closed_) {
      return util::Status(util::error::FAILED_PRECONDITION,
                          "Write on closed Stream");
    }
    return NextBuffer(data);
  }

 protected:
  // Compute the result for this OutputStream. Safe for thread safety problems,
  // this method will only be called once.
  // The return type is StatusOr<T> if T != Status, and Status otherwise.
  virtual ResultType CloseStreamAndComputeResult() = 0;
  // Getting the next OutputStream buffer. See OutputStream for detailed
  // description.
  virtual util::StatusOr<int> NextBuffer(void** data) = 0;

 private:
  bool closed_;
  ResultType result_;
};

}  // namespace tink
}  // namespace crypto

#endif  // TINK_OUTPUT_STREAM_WITH_RESULT_H_
