// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_CRDTP_DISPATCH_H_
#define V8_CRDTP_DISPATCH_H_

#include <cassert>
#include <cstdint>
#include <functional>
#include <string>
#include <unordered_set>
#include "export.h"
#include "serializable.h"
#include "span.h"
#include "status.h"

namespace v8_crdtp {
class DeserializerState;
class ErrorSupport;
class FrontendChannel;
namespace cbor {
class CBORTokenizer;
}  // namespace cbor

// =============================================================================
// DispatchResponse - Error status and chaining / fall through
// =============================================================================
enum class DispatchCode {
  SUCCESS = 1,
  FALL_THROUGH = 2,
  // For historical reasons, these error codes correspond to commonly used
  // XMLRPC codes (e.g. see METHOD_NOT_FOUND in
  // https://github.com/python/cpython/blob/master/Lib/xmlrpc/client.py).
  PARSE_ERROR = -32700,
  INVALID_REQUEST = -32600,
  METHOD_NOT_FOUND = -32601,
  INVALID_PARAMS = -32602,
  INTERNAL_ERROR = -32603,
  SERVER_ERROR = -32000,
};

// Information returned by command handlers. Usually returned after command
// execution attempts.
class DispatchResponse {
 public:
  const std::string& Message() const { return message_; }

  DispatchCode Code() const { return code_; }

  bool IsSuccess() const { return code_ == DispatchCode::SUCCESS; }
  bool IsFallThrough() const { return code_ == DispatchCode::FALL_THROUGH; }
  bool IsError() const { return code_ < DispatchCode::SUCCESS; }

  static DispatchResponse Success();
  static DispatchResponse FallThrough();

  // Indicates that a message could not be parsed. E.g., malformed JSON.
  static DispatchResponse ParseError(std::string message);

  // Indicates that a request is lacking required top-level properties
  // ('id', 'method'), has top-level properties of the wrong type, or has
  // unknown top-level properties.
  static DispatchResponse InvalidRequest(std::string message);

  // Indicates that a protocol method such as "Page.bringToFront" could not be
  // dispatched because it's not known to the (domain) dispatcher.
  static DispatchResponse MethodNotFound(std::string message);

  // Indicates that the params sent to a domain handler are invalid.
  static DispatchResponse InvalidParams(std::string message);

  // Used for application level errors, e.g. within protocol agents.
  static DispatchResponse InternalError();

  // Used for application level errors, e.g. within protocol agents.
  static DispatchResponse ServerError(std::string message);

 private:
  DispatchResponse() = default;
  DispatchCode code_;
  std::string message_;
};

// =============================================================================
// Dispatchable - a shallow parser for CBOR encoded DevTools messages
// =============================================================================

// This parser extracts only the known top-level fields from a CBOR encoded map;
// method, id, sessionId, and params.
class Dispatchable {
 public:
  // This constructor parses the |serialized| message. If successful,
  // |ok()| will yield |true|, and |Method()|, |SessionId()|, |CallId()|,
  // |Params()| can be used to access, the extracted contents. Otherwise,
  // |ok()| will yield |false|, and |DispatchError()| can be
  // used to send a response or notification to the client.
  explicit Dispatchable(span<uint8_t> serialized);

  // The serialized message that we just parsed.
  span<uint8_t> Serialized() const { return serialized_; }

  // Yields true if parsing was successful. This is cheaper than calling
  // ::DispatchError().
  bool ok() const;

  // If !ok(), returns a DispatchResponse with appropriate code and error
  // which can be sent to the client as a response or notification.
  DispatchResponse DispatchError() const;

  // Top level field: the command to be executed, fully qualified by
  // domain. E.g. "Page.createIsolatedWorld".
  span<uint8_t> Method() const { return method_; }
  // Used to identify protocol connections attached to a specific
  // target. See Target.attachToTarget, Target.setAutoAttach.
  span<uint8_t> SessionId() const { return session_id_; }
  // The call id, a sequence number that's used in responses to indicate
  // the request to which the response belongs.
  int32_t CallId() const { return call_id_; }
  bool HasCallId() const { return has_call_id_; }
  // The payload of the request in CBOR format. The |Dispatchable| parser does
  // not parse into this; it only provides access to its raw contents here.
  span<uint8_t> Params() const { return params_; }

 private:
  bool MaybeParseProperty(cbor::CBORTokenizer* tokenizer);
  bool MaybeParseCallId(cbor::CBORTokenizer* tokenizer);
  bool MaybeParseMethod(cbor::CBORTokenizer* tokenizer);
  bool MaybeParseParams(cbor::CBORTokenizer* tokenizer);
  bool MaybeParseSessionId(cbor::CBORTokenizer* tokenizer);

  span<uint8_t> serialized_;

  Status status_;

  bool has_call_id_ = false;
  int32_t call_id_;
  span<uint8_t> method_;
  bool params_seen_ = false;
  span<uint8_t> params_;
  span<uint8_t> session_id_;
};

// =============================================================================
// Helpers for creating protocol cresponses and notifications.
// =============================================================================

// The resulting notifications can be sent to a protocol client,
// usually via a FrontendChannel (see frontend_channel.h).

std::unique_ptr<Serializable> CreateErrorResponse(
    int callId,
    DispatchResponse dispatch_response,
    const ErrorSupport* errors = nullptr);

std::unique_ptr<Serializable> CreateErrorNotification(
    DispatchResponse dispatch_response);

std::unique_ptr<Serializable> CreateResponse(
    int callId,
    std::unique_ptr<Serializable> params);

std::unique_ptr<Serializable> CreateNotification(
    const char* method,
    std::unique_ptr<Serializable> params = nullptr);

// =============================================================================
// DomainDispatcher - Dispatching betwen protocol methods within a domain.
// =============================================================================

// This class is subclassed by |DomainDispatcherImpl|, which we generate per
// DevTools domain. It contains routines called from the generated code,
// e.g. ::MaybeReportInvalidParams, which are optimized for small code size.
// The most important method is ::Dispatch, which implements method dispatch
// by command name lookup.
class DomainDispatcher {
 public:
  class WeakPtr {
   public:
    explicit WeakPtr(DomainDispatcher*);
    ~WeakPtr();
    DomainDispatcher* get() { return dispatcher_; }
    void dispose() { dispatcher_ = nullptr; }

   private:
    DomainDispatcher* dispatcher_;
  };

  class Callback {
   public:
    virtual ~Callback();
    void dispose();

   protected:
    // |method| must point at static storage (a C++ string literal in practice).
    Callback(std::unique_ptr<WeakPtr> backend_impl,
             int call_id,
             span<uint8_t> method,
             span<uint8_t> message);

    void sendIfActive(std::unique_ptr<Serializable> partialMessage,
                      const DispatchResponse& response);
    void fallThroughIfActive();

   private:
    std::unique_ptr<WeakPtr> backend_impl_;
    int call_id_;
    // Subclasses of this class are instantiated from generated code which
    // passes a string literal for the method name to the constructor. So the
    // storage for |method| is the binary of the running process.
    span<uint8_t> method_;
    std::vector<uint8_t> message_;
  };

  explicit DomainDispatcher(FrontendChannel*);
  virtual ~DomainDispatcher();

  // Given a |command_name| without domain qualification, looks up the
  // corresponding method. If the method is not found, returns nullptr.
  // Otherwise, Returns a closure that will parse the provided
  // Dispatchable.params() to a protocol object and execute the
  // apprpropriate method. If the parsing fails it will issue an
  // error response on the frontend channel, otherwise it will execute the
  // command.
  virtual std::function<void(const Dispatchable&)> Dispatch(
      span<uint8_t> command_name) = 0;

  // Sends a response to the client via the channel.
  void sendResponse(int call_id,
                    const DispatchResponse&,
                    std::unique_ptr<Serializable> result = nullptr);

  // Returns true if |errors| contains errors *and* reports these errors
  // as a response on the frontend channel. Called from generated code,
  // optimized for code size of the callee.
  bool MaybeReportInvalidParams(const Dispatchable& dispatchable,
                                const ErrorSupport& errors);
  bool MaybeReportInvalidParams(const Dispatchable& dispatchable,
                                const DeserializerState& state);

  FrontendChannel* channel() { return frontend_channel_; }

  void clearFrontend();

  std::unique_ptr<WeakPtr> weakPtr();

 private:
  FrontendChannel* frontend_channel_;
  std::unordered_set<WeakPtr*> weak_ptrs_;
};

// =============================================================================
// UberDispatcher - dispatches between domains (backends).
// =============================================================================
class UberDispatcher {
 public:
  // Return type for ::Dispatch.
  class DispatchResult {
   public:
    DispatchResult(bool method_found, std::function<void()> runnable);

    // Indicates whether the method was found, that is, it could be dispatched
    // to a backend registered with this dispatcher.
    bool MethodFound() const { return method_found_; }

    // Runs the dispatched result. This will send the appropriate error
    // responses if the method wasn't found or if something went wrong during
    // parameter parsing.
    void Run();

   private:
    bool method_found_;
    std::function<void()> runnable_;
  };

  // |frontend_hannel| can't be nullptr.
  explicit UberDispatcher(FrontendChannel* frontend_channel);
  virtual ~UberDispatcher();

  // Dispatches the provided |dispatchable| considering all redirects and domain
  // handlers registered with this uber dispatcher. Also see |DispatchResult|.
  // |dispatchable.ok()| must hold - callers must check this separately and
  // deal with errors.
  DispatchResult Dispatch(const Dispatchable& dispatchable) const;

  // Invoked from generated code for wiring domain backends; that is,
  // connecting domain handlers to an uber dispatcher.
  // See <domain-namespace>::Dispatcher::Wire(UberDispatcher*,Backend*).
  FrontendChannel* channel() const {
    assert(frontend_channel_);
    return frontend_channel_;
  }

  // Invoked from generated code for wiring domain backends; that is,
  // connecting domain handlers to an uber dispatcher.
  // See <domain-namespace>::Dispatcher::Wire(UberDispatcher*,Backend*).
  void WireBackend(span<uint8_t> domain,
                   const std::vector<std::pair<span<uint8_t>, span<uint8_t>>>&,
                   std::unique_ptr<DomainDispatcher> dispatcher);

 private:
  DomainDispatcher* findDispatcher(span<uint8_t> method);
  FrontendChannel* const frontend_channel_;
  // Pairs of ascii strings of the form ("Domain1.method1","Domain2.method2")
  // indicating that the first element of each pair redirects to the second.
  // Sorted by first element.
  std::vector<std::pair<span<uint8_t>, span<uint8_t>>> redirects_;
  // Domain dispatcher instances, sorted by their domain name.
  std::vector<std::pair<span<uint8_t>, std::unique_ptr<DomainDispatcher>>>
      dispatchers_;
};
}  // namespace v8_crdtp

#endif  // V8_CRDTP_DISPATCH_H_
