/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef test_io_h_
#define test_io_h_

#include <string.h>
#include <map>
#include <memory>
#include <ostream>
#include <queue>
#include <string>

#include "databuffer.h"
#include "dummy_io.h"
#include "prio.h"
#include "nss_scoped_ptrs.h"
#include "sslt.h"

namespace nss_test {

class DataBuffer;
class DummyPrSocket;  // Fwd decl.

// Allow us to inspect a packet before it is written.
class PacketFilter {
 public:
  enum Action {
    KEEP,    // keep the original packet unmodified
    CHANGE,  // change the packet to a different value
    DROP     // drop the packet
  };
  explicit PacketFilter(bool on = true) : enabled_(on) {}
  virtual ~PacketFilter() {}

  bool enabled() const { return enabled_; }

  virtual Action Process(const DataBuffer& input, DataBuffer* output) {
    if (!enabled_) {
      return KEEP;
    }
    return Filter(input, output);
  }
  void Enable() { enabled_ = true; }
  void Disable() { enabled_ = false; }

  // The packet filter takes input and has the option of mutating it.
  //
  // A filter that modifies the data places the modified data in *output and
  // returns CHANGE.  A filter that does not modify data returns LEAVE, in which
  // case the value in *output is ignored.  A Filter can return DROP, in which
  // case the packet is dropped (and *output is ignored).
  virtual Action Filter(const DataBuffer& input, DataBuffer* output) = 0;

 private:
  bool enabled_;
};

class DummyPrSocket : public DummyIOLayerMethods {
 public:
  DummyPrSocket(const std::string& name, SSLProtocolVariant var)
      : name_(name),
        variant_(var),
        peer_(),
        input_(),
        filter_(nullptr),
        write_error_(0) {}
  virtual ~DummyPrSocket() {}

  static PRDescIdentity LayerId();

  // Create a file descriptor that will reference this object.  The fd must not
  // live longer than this adapter; call PR_Close() before.
  ScopedPRFileDesc CreateFD();

  std::weak_ptr<DummyPrSocket>& peer() { return peer_; }
  void SetPeer(const std::shared_ptr<DummyPrSocket>& p) { peer_ = p; }
  void SetPacketFilter(const std::shared_ptr<PacketFilter>& filter) {
    filter_ = filter;
  }
  // Drops peer, packet filter and any outstanding packets.
  void Reset();

  void PacketReceived(const DataBuffer& data);
  int32_t Read(PRFileDesc* f, void* data, int32_t len) override;
  int32_t Recv(PRFileDesc* f, void* buf, int32_t buflen, int32_t flags,
               PRIntervalTime to) override;
  int32_t Write(PRFileDesc* f, const void* buf, int32_t length) override;
  void SetWriteError(PRErrorCode code) { write_error_ = code; }

  SSLProtocolVariant variant() const { return variant_; }
  bool readable() const { return !input_.empty(); }

 private:
  class Packet : public DataBuffer {
   public:
    Packet(const DataBuffer& buf) : DataBuffer(buf), offset_(0) {}

    void Advance(size_t delta) {
      PR_ASSERT(offset_ + delta <= len());
      offset_ = std::min(len(), offset_ + delta);
    }

    size_t offset() const { return offset_; }
    size_t remaining() const { return len() - offset_; }

   private:
    size_t offset_;
  };

  const std::string name_;
  SSLProtocolVariant variant_;
  std::weak_ptr<DummyPrSocket> peer_;
  std::queue<Packet> input_;
  std::shared_ptr<PacketFilter> filter_;
  PRErrorCode write_error_;
};

// Marker interface.
class PollTarget {};

enum Event { READABLE_EVENT, TIMER_EVENT /* Must be last */ };

typedef void (*PollCallback)(PollTarget*, Event);

class Poller {
 public:
  static Poller* Instance();  // Get a singleton.
  static void Shutdown();     // Shut it down.

  class Timer {
   public:
    Timer(PRTime deadline, PollTarget* target, PollCallback callback)
        : deadline_(deadline), target_(target), callback_(callback) {}
    void Cancel() { callback_ = nullptr; }

    PRTime deadline_;
    PollTarget* target_;
    PollCallback callback_;
  };

  void Wait(Event event, std::shared_ptr<DummyPrSocket>& adapter,
            PollTarget* target, PollCallback cb);
  void Cancel(Event event, std::shared_ptr<DummyPrSocket>& adapter);
  void SetTimer(uint32_t timer_ms, PollTarget* target, PollCallback cb,
                std::shared_ptr<Timer>* handle);
  bool Poll();

 private:
  Poller() : waiters_(), timers_() {}
  ~Poller() {}

  class Waiter {
   public:
    Waiter(std::shared_ptr<DummyPrSocket> io) : io_(io) {
      memset(&targets_[0], 0, sizeof(targets_));
      memset(&callbacks_[0], 0, sizeof(callbacks_));
    }

    void WaitFor(Event event, PollCallback callback);

    std::shared_ptr<DummyPrSocket> io_;
    PollTarget* targets_[TIMER_EVENT];
    PollCallback callbacks_[TIMER_EVENT];
  };

  class TimerComparator {
   public:
    bool operator()(const std::shared_ptr<Timer> lhs,
                    const std::shared_ptr<Timer> rhs) {
      return lhs->deadline_ > rhs->deadline_;
    }
  };

  static Poller* instance;
  std::map<std::shared_ptr<DummyPrSocket>, std::unique_ptr<Waiter>> waiters_;
  std::priority_queue<std::shared_ptr<Timer>,
                      std::vector<std::shared_ptr<Timer>>, TimerComparator>
      timers_;
};

}  // namespace nss_test

#endif
