// 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 <openssl/bio.h>
#include <openssl/pem.h>
#include <openssl/ssl.h>

#include "pw_bytes/span.h"
#include "pw_result/result.h"
#include "pw_status/status.h"
#include "pw_stream/stream.h"

namespace pw::boringssl {

class FixedSizeFIFOBuffer : public stream::ReaderWriter {
 public:
  FixedSizeFIFOBuffer() = delete;
  FixedSizeFIFOBuffer(const FixedSizeFIFOBuffer&) = delete;
  FixedSizeFIFOBuffer& operator=(const FixedSizeFIFOBuffer&) = delete;

  FixedSizeFIFOBuffer(ByteSpan buffer) : buffer_(buffer) {}
  void clear() { current_size_ = 0; }

 private:
  StatusWithSize DoRead(ByteSpan dest) override;
  Status DoWrite(ConstByteSpan data) override;
  ByteSpan buffer_;
  size_t current_size_ = 0;
};

// Writing to the server is equivalent to sending data to the server. Server
// will be invoked to process the data when being written. The write does
// not return until the server completes processing it.
// Reading from the server is equivalent to receiving data from the server.
//
// The server accepts is only for one client and echo messages it sends.
class InMemoryTestServer : public stream::ReaderWriter {
 public:
  InMemoryTestServer() = delete;
  InMemoryTestServer(const InMemoryTestServer&) = delete;
  InMemoryTestServer& operator=(const InMemoryTestServer&) = delete;

  // `input_buffer` is for storing raw data sent from the client.
  // `output_buffer` is for storing raw data server prepare and to be sent
  // to the client.
  //
  // The required size of the buffer depends on the payload and needs to be
  // determined by the users based on use cases.
  InMemoryTestServer(ByteSpan input_buffer, ByteSpan output_buffer);

  // Initialize a test server with a private key, server certificate, and
  // CA chains (all DER format)
  Status Initialize(ConstByteSpan key,
                    ConstByteSpan cert,
                    std::span<const ConstByteSpan> chains);

  // Is handshake completed.
  bool SessionEstablished() { return is_handshake_done_; }

  // Returns whether a shutdown request has been received from the client.
  bool ClientShutdownReceived();

  Status GetLastBioStatus() { return last_bio_status_; }

 private:
  bssl::UniquePtr<SSL_CTX> ctx_;
  bssl::UniquePtr<SSL> ssl_;
  bool is_handshake_done_ = false;

  // Buffer for storing data sent from the client.
  FixedSizeFIFOBuffer input_buffer_;

  // Buffer for storing data prepared by the server to send to the client.
  FixedSizeFIFOBuffer output_buffer_;

  // Store the last status of BIO operation (in BioRead() and BioWrite());
  Status last_bio_status_ = OkStatus();

  // Process the data written to the server as much as possible.
  // If server is in handshake process, it processes handshake and prepares data
  // to send to the server . If server is in application data exchange
  // phase, it decrypts data and echoes back to the client. Client can retrieve
  // the message by reading from the server.
  Status ProcessPackets();

  // Methods for loading private key, certificate, and intermediate CA chain.
  Status LoadPrivateKey(ConstByteSpan key);
  Status LoadCertificate(ConstByteSpan cert);
  Status LoadCAChain(std::span<const ConstByteSpan> chains);

  // Methods for providing BIO interfaces.
  static int BioRead(BIO* bio, char* out, int outl);
  static int BioWrite(BIO* bio, const char* in, int inl);

  StatusWithSize DoRead(ByteSpan dest) override;
  Status DoWrite(ConstByteSpan data) override;
};

// A helper function to parse a DER format certificate.
pw::Result<X509*> ParseDerCertificate(pw::ConstByteSpan cert);

}  // namespace pw::boringssl
