// Copyright 2019 Google LLC
//
// 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.

#ifndef dap_session_h
#define dap_session_h

#include "future.h"
#include "io.h"
#include "typeinfo.h"
#include "typeof.h"

#include <functional>

namespace dap {

// Forward declarations
struct Request;
struct Response;
struct Event;

// internal functionality
namespace detail {
template <typename T>
struct traits {
  static constexpr bool isRequest = std::is_base_of<dap::Request, T>::value;
  static constexpr bool isResponse = std::is_base_of<dap::Response, T>::value;
  static constexpr bool isEvent = std::is_base_of<dap::Event, T>::value;
};

// ArgTy<F>::type resolves to the first argument type of the function F.
// F can be a function, static member function, or lambda.
template <typename F>
struct ArgTy {
  using type = typename ArgTy<decltype(&F::operator())>::type;
};

template <typename R, typename Arg>
struct ArgTy<R (*)(Arg)> {
  using type = typename std::decay<Arg>::type;
};

template <typename R, typename C, typename Arg>
struct ArgTy<R (C::*)(Arg) const> {
  using type = typename std::decay<Arg>::type;
};
}  // namespace detail

////////////////////////////////////////////////////////////////////////////////
// Error
////////////////////////////////////////////////////////////////////////////////

// Error represents an error message in response to a DAP request.
struct Error {
  Error() = default;
  Error(const std::string& error);
  Error(const char* msg, ...);

  // operator bool() returns true if there is an error.
  inline operator bool() const { return message.size() > 0; }

  std::string message;  // empty represents success.
};

////////////////////////////////////////////////////////////////////////////////
// ResponseOrError<T>
////////////////////////////////////////////////////////////////////////////////

// ResponseOrError holds either the response to a DAP request or an error
// message.
template <typename T>
struct ResponseOrError {
  using Request = T;

  inline ResponseOrError() = default;
  inline ResponseOrError(const T& response);
  inline ResponseOrError(const Error& error);
  inline ResponseOrError(const ResponseOrError& other);

  T response;
  Error error;  // empty represents success.
};

template <typename T>
ResponseOrError<T>::ResponseOrError(const T& response) : response(response) {}
template <typename T>
ResponseOrError<T>::ResponseOrError(const Error& error) : error(error) {}
template <typename T>
ResponseOrError<T>::ResponseOrError(const ResponseOrError& other)
    : response(other.response), error(other.error) {}

////////////////////////////////////////////////////////////////////////////////
// Session
////////////////////////////////////////////////////////////////////////////////

// Session implements a DAP client or server endpoint.
// The general usage is as follows:
// (1) Create a session with Session::create().
// (2) Register request and event handlers with registerHandler().
// (3) Optionally register a protocol error handler with onError().
// (3) Bind the session to the remote endpoint with bind().
// (4) Send requests or events with send().
class Session {
  template <typename T>
  using IsRequest = typename std::enable_if<detail::traits<T>::isRequest>::type;

  template <typename T>
  using IsEvent = typename std::enable_if<detail::traits<T>::isEvent>::type;

  template <typename F>
  using ArgTy = typename detail::ArgTy<F>::type;

 public:
  virtual ~Session() = default;

  // ErrorHandler is the type of callback function used for reporting protocol
  // errors.
  using ErrorHandler = std::function<void(const char*)>;

  // create() constructs and returns a new Session.
  static std::unique_ptr<Session> create();

  // onError() registers a error handler that will be called whenever a protocol
  // error is encountered.
  // Only one error handler can be bound at any given time, and later calls
  // will replace the existing error handler.
  virtual void onError(const ErrorHandler&) = 0;

  // registerHandler() registers a request handler for a specific request type.
  // The function F must have one of the following signatures:
  //   ResponseOrError<ResponseType>(const RequestType&)
  //   ResponseType(const RequestType&)
  //   Error(const RequestType&)
  template <typename F, typename RequestType = ArgTy<F>>
  inline IsRequest<RequestType> registerHandler(F&& handler);

  // registerHandler() registers a event handler for a specific event type.
  // The function F must have the following signature:
  //   void(const EventType&)
  template <typename F, typename EventType = ArgTy<F>>
  inline IsEvent<EventType> registerHandler(F&& handler);

  // registerSentHandler() registers the function F to be called when a response
  // of the specific type has been sent.
  // The function F must have the following signature:
  //   void(const ResponseOrError<ResponseType>&)
  template <typename F, typename ResponseType = typename ArgTy<F>::Request>
  inline void registerSentHandler(F&& handler);

  // send() sends the request to the connected endpoint and returns a
  // future that is assigned the request response or error.
  template <typename T, typename = IsRequest<T>>
  future<ResponseOrError<typename T::Response>> send(const T& request);

  // send() sends the event to the connected endpoint.
  template <typename T, typename = IsEvent<T>>
  void send(const T& event);

  // bind() connects this Session to an endpoint.
  // bind() can only be called once. Repeated calls will raise an error, but
  // otherwise will do nothing.
  virtual void bind(const std::shared_ptr<Reader>&,
                    const std::shared_ptr<Writer>&) = 0;
  inline void bind(const std::shared_ptr<ReaderWriter>&);

 protected:
  using RequestSuccessCallback =
      std::function<void(const TypeInfo*, const void*)>;

  using RequestErrorCallback =
      std::function<void(const TypeInfo*, const Error& message)>;

  using GenericResponseHandler = std::function<void(const void*, const Error*)>;

  using GenericRequestHandler =
      std::function<void(const void* args,
                         const RequestSuccessCallback& onSuccess,
                         const RequestErrorCallback& onError)>;

  using GenericEventHandler = std::function<void(const void* args)>;

  using GenericResponseSentHandler =
      std::function<void(const void* response, const Error* error)>;

  virtual void registerHandler(const TypeInfo* typeinfo,
                               const GenericRequestHandler& handler) = 0;

  virtual void registerHandler(const TypeInfo* typeinfo,
                               const GenericEventHandler& handler) = 0;

  virtual void registerHandler(const TypeInfo* typeinfo,
                               const GenericResponseSentHandler& handler) = 0;

  virtual bool send(const dap::TypeInfo* typeinfo,
                    const void* request,
                    const GenericResponseHandler& responseHandler) = 0;

  virtual bool send(const TypeInfo*, const void* event) = 0;
};

template <typename F, typename T>
Session::IsRequest<T> Session::registerHandler(F&& handler) {
  using ResponseType = typename T::Response;
  auto cb = [handler](const void* args, const RequestSuccessCallback& onSuccess,
                      const RequestErrorCallback& onError) {
    ResponseOrError<ResponseType> res =
        handler(*reinterpret_cast<const T*>(args));
    if (res.error) {
      onError(TypeOf<ResponseType>::type(), res.error);
    } else {
      onSuccess(TypeOf<ResponseType>::type(), &res.response);
    }
  };
  const TypeInfo* typeinfo = TypeOf<T>::type();
  registerHandler(typeinfo, cb);
}

template <typename F, typename T>
Session::IsEvent<T> Session::registerHandler(F&& handler) {
  auto cb = [handler](const void* args) {
    handler(*reinterpret_cast<const T*>(args));
  };
  const TypeInfo* typeinfo = TypeOf<T>::type();
  registerHandler(typeinfo, cb);
}

template <typename F, typename T>
void Session::registerSentHandler(F&& handler) {
  auto cb = [handler](const void* response, const Error* error) {
    if (error != nullptr) {
      handler(ResponseOrError<T>(*error));
    } else {
      handler(ResponseOrError<T>(*reinterpret_cast<const T*>(response)));
    }
  };
  const TypeInfo* typeinfo = TypeOf<T>::type();
  registerHandler(typeinfo, cb);
}

template <typename T, typename>
future<ResponseOrError<typename T::Response>> Session::send(const T& request) {
  using Response = typename T::Response;
  promise<ResponseOrError<Response>> promise;
  const TypeInfo* typeinfo = TypeOf<T>::type();
  auto sent =
      send(typeinfo, &request, [=](const void* result, const Error* error) {
        if (error != nullptr) {
          promise.set_value(ResponseOrError<Response>(*error));
        } else {
          promise.set_value(ResponseOrError<Response>(
              *reinterpret_cast<const Response*>(result)));
        }
      });
  if (!sent) {
    promise.set_value(Error("Failed to send request"));
  }
  return promise.get_future();
}

template <typename T, typename>
void Session::send(const T& event) {
  const TypeInfo* typeinfo = TypeOf<T>::type();
  send(typeinfo, &event);
}

void Session::bind(const std::shared_ptr<ReaderWriter>& rw) {
  bind(rw, rw);
}

}  // namespace dap

#endif  // dap_session_h
