// 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::tls_client::test {

class FixedSizeFIFOBuffer : public stream::NonSeekableReaderWriter {
 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::NonSeekableReaderWriter {
 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 output_length);
  static int BioWrite(BIO* bio, const char* in, int input_length);

  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::tls_client::test
