// Copyright 2017 The Cobalt Authors. All Rights Reserved.
//
// 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 STARBOARD_SHARED_WIN32_SOCKET_WAITER_INTERNAL_H_
#define STARBOARD_SHARED_WIN32_SOCKET_WAITER_INTERNAL_H_

#include <windows.h>
#include <winsock2.h>

#include <deque>
#include <memory>
#include <unordered_map>
#include <vector>

#include "starboard/common/mutex.h"
#include "starboard/common/optional.h"
#include "starboard/common/socket.h"
#include "starboard/shared/internal_only.h"
#include "starboard/shared/win32/auto_event_handle.h"
#include "starboard/shared/win32/socket_internal.h"
#include "starboard/socket_waiter.h"
#include "starboard/thread.h"
#include "starboard/types.h"

namespace sbwin32 = starboard::shared::win32;

#pragma warning(push)

// SbSocketWaiterPrivate is defined as a struct, but for windows implementation
// enough functionality has been added so that it warrants being a class
// per Google's C++ style guide.  This mismatch causes the Microsoft's compiler
// to generate a warning.
#pragma warning(disable : 4099)
class SbSocketWaiterPrivate {
 public:
  SbSocketWaiterPrivate();
  ~SbSocketWaiterPrivate();

  // These methods implement the SbSocketWaiter API defined in socket_waiter.h.
  bool Add(SbSocket socket,
           void* context,
           SbSocketWaiterCallback callback,
           int interests,
           bool persistent);
  bool Remove(SbSocket socket);
  void Wait();
  SbSocketWaiterResult WaitTimed(int64_t duration_usec);
  void WakeUp();
  void HandleWakeUpRead();

 private:
  // A registration of a socket with a socket waiter.
  struct Waitee {
    Waitee(SbSocketWaiter waiter,
           SbSocket socket,
           void* context,
           SbSocketWaiterCallback callback,
           int interests,
           bool persistent)
        : waiter(waiter),
          socket(socket),
          context(context),
          callback(callback),
          interests(interests),
          persistent(persistent) {}
    // The waiter this event is registered with.
    SbSocketWaiter waiter;

    // The socket registered with the waiter.
    SbSocket socket;

    // A context value that will be passed to the callback.
    void* context;

    // The callback to call when one or more registered interests become ready.
    SbSocketWaiterCallback callback;

    // The set of interests registered with the waiter.
    int interests;

    // Whether this Waitee should stay registered after the next callback.
    bool persistent;
  };

  class WaiteeRegistry {
   public:
    typedef int64_t LookupToken;
    typedef std::deque<std::unique_ptr<Waitee>> Waitees;
    typedef std::unordered_map<SbSocket, std::size_t> SocketToIndex;

    WSAEVENT* GetHandleArray() { return socket_events_.data(); }
    std::size_t GetHandleArraySize() { return socket_events_.size(); }
    const Waitees& GetWaitees() const { return waitees_; }

    // Gets the Waitee associated with the given socket, or nullptr.
    Waitee* GetWaitee(SbSocket socket);

    // Gets the index by socket
    starboard::optional<int64_t> GetIndex(SbSocket socket);

    // Gets the Waitee by index.
    Waitee* GetWaiteeByIndex(LookupToken socket_index);

    // Returns the index of the event.
    LookupToken AddSocketEventAndWaitee(WSAEVENT socket_event,
                                        std::unique_ptr<Waitee> waitee);
    // Returns true if socket was found, and removed.
    bool RemoveSocket(SbSocket socket);

   private:
    SocketToIndex socket_to_index_map_;
    std::vector<WSAEVENT> socket_events_;
    std::deque<std::unique_ptr<Waitee>> waitees_;
  };

  void SignalWakeupEvent();
  void ResetWakeupEvent();

  bool CheckSocketWaiterIsThis(SbSocket socket);

  // The thread this waiter was created on. Immutable, so accessible from any
  // thread.
  const pthread_t thread_;

  // The registry of currently registered Waitees.
  WaiteeRegistry waitees_;
  WaiteeRegistry::LookupToken wakeup_event_token_;

  // This mutex covers the next two variables.
  starboard::Mutex unhandled_wakeup_count_mutex_;
  // Number of times wake up has been called, and not handled.
  std::int32_t unhandled_wakeup_count_;
  // The WSAEvent that is set by Wakeup();
  sbwin32::AutoEventHandle wakeup_event_;
};
#pragma warning(pop)

#endif  // STARBOARD_SHARED_WIN32_SOCKET_WAITER_INTERNAL_H_
