// Copyright 2021 The Pigweed Authors
//
// 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
//
//     https://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.
#pragma once

#include <limits>

#include "pw_bytes/span.h"
#include "pw_transfer/handler.h"
#include "pw_transfer/internal/context.h"
#include "pw_transfer/transfer.raw_rpc.pb.h"

namespace pw::transfer {

class TransferService : public generated::Transfer<TransferService> {
 public:
  // Initializes a TransferService that can be registered with an RPC server.
  //
  // max_chunk_size_bytes is the largest amount of data that can be sent within
  // a single transfer chunk (read or write), excluding any transport layer
  // overhead. Not all of this size is used to send data -- there is additional
  // overhead in the pw_rpc and pw_transfer protocols (typically ~22B/chunk).
  //
  // default_max_bytes_to_receive is the maximum amount of data to ask for at a
  // time during a write transfer, unless told a more restrictive amount by a
  // transfer handler. This size can span multiple chunks. A larger value
  // generally increases the efficiency of write transfers when sent over a
  // reliable transport. However, if the underlying transport is unreliable,
  // larger values could slow down a transfer in the event of repeated packet
  // loss.
  constexpr TransferService(size_t max_chunk_size_bytes,
                            size_t default_max_bytes_to_receive)
      : read_transfers_(internal::Context::kRead, handlers_),
        write_transfers_(internal::Context::kWrite, handlers_),
        max_chunk_size_bytes_(max_chunk_size_bytes),
        default_max_bytes_to_receive_(default_max_bytes_to_receive) {}

  void Read(ServerContext&, RawServerReaderWriter& reader_writer);

  void Write(ServerContext&, RawServerReaderWriter& reader_writer);

  void RegisterHandler(internal::Handler& handler) {
    handlers_.push_front(handler);
  }

 private:
  void SendStatusChunk(RawServerReaderWriter& stream,
                       uint32_t transfer_id,
                       Status status);

  // Sends a out data chunk for a read transfer. Returns true if the data was
  // sent successfully.
  bool SendNextReadChunk(internal::Context& context);

  void OnReadMessage(ConstByteSpan message);
  void OnWriteMessage(ConstByteSpan message);

  size_t MaxWriteChunkSize(const internal::Context& transfer) const;

  // All registered transfer handlers.
  IntrusiveList<internal::Handler> handlers_;

  // Persistent streams for read and write transfers. The server never closes
  // these streams -- they remain open until the client ends them.
  RawServerReaderWriter read_stream_;
  RawServerReaderWriter write_stream_;

  internal::ContextPool read_transfers_;
  internal::ContextPool write_transfers_;

  size_t max_chunk_size_bytes_;
  size_t default_max_bytes_to_receive_;
};

}  // namespace pw::transfer
