// Copyright 2017 The Crashpad 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 CRASHPAD_HANDLER_LINUX_EXCEPTION_HANDLER_SERVER_H_
#define CRASHPAD_HANDLER_LINUX_EXCEPTION_HANDLER_SERVER_H_

#include <stdint.h>
#include <sys/socket.h>

#include <atomic>
#include <memory>
#include <unordered_map>

#include "base/macros.h"
#include "util/file/file_io.h"
#include "util/linux/exception_handler_protocol.h"
#include "util/misc/address_types.h"
#include "util/misc/initialization_state_dcheck.h"
#include "util/misc/uuid.h"

namespace crashpad {

//! \brief Abstract base class for deciding how the handler should `ptrace` a
//!     client.
class PtraceStrategyDecider {
 public:
  virtual ~PtraceStrategyDecider() = default;

  //! \brief The possible return values for ChooseStrategy().
  enum class Strategy {
    //! \brief An error occurred,  with a message logged.
    kError,

    //! \brief Ptrace cannot be used.
    kNoPtrace,

    //! \brief The handler should `ptrace`-attach the client directly.
    kDirectPtrace,

    //! \brief The client has `fork`ed a PtraceBroker for the handler.
    kUseBroker,
  };

  //! \brief Chooses an appropriate `ptrace` strategy.
  //!
  //! \param[in] sock A socket conncted to a ExceptionHandlerClient.
  //! \param[in] multiple_clients `true` if the socket is connected to multiple
  //!     clients. The broker is not supported in this configuration.
  //! \param[in] client_credentials The credentials for the connected client.
  //! \return the chosen #Strategy.
  virtual Strategy ChooseStrategy(int sock,
                                  bool multiple_clients,
                                  const ucred& client_credentials) = 0;

 protected:
  PtraceStrategyDecider() = default;
};

//! \brief Runs the main exception-handling server in Crashpad’s handler
//!     process.
class ExceptionHandlerServer {
 public:
  class Delegate {
   public:
    //! \brief Called on receipt of a crash dump request from a client.
    //!
    //! \param[in] client_process_id The process ID of the crashing client.
    //! \param[in] client_uid The user ID of the crashing client.
    //! \param[in] info Information on the client.
    //! \param[in] requesting_thread_stack_address Any address within the stack
    //!     range for the the thread that sent the crash dump request. Optional.
    //!     If unspecified or 0, \a requesting_thread_id will be -1.
    //! \param[out] requesting_thread_id The thread ID of the thread which
    //!     requested the crash dump if not `nullptr`. Set to -1 if the thread
    //!     ID could not be determined. Optional.
    //! \param[out] local_report_id The unique identifier for the report created
    //!     in the local report database. Optional.
    //! \return `true` on success. `false` on failure with a message logged.
    virtual bool HandleException(
        pid_t client_process_id,
        uid_t client_uid,
        const ExceptionHandlerProtocol::ClientInformation& info,
        VMAddress requesting_thread_stack_address = 0,
        pid_t* requesting_thread_id = nullptr,
        UUID* local_report_id = nullptr) = 0;

#if defined(STARBOARD)
    //! \brief Called on receipt of a request to add Evergreen mapping info.
    //!
    //! \param[in] info Information on the client.
    //! \return `true` on success. `false` on failure with a message logged.
    virtual bool AddEvergreenInfo(
        const ExceptionHandlerProtocol::ClientInformation& info) = 0;
#endif

    //! \brief Called on the receipt of a crash dump request from a client for a
    //!     crash that should be mediated by a PtraceBroker.
    //!
    //! \param[in] client_process_id The process ID of the crashing client.
    //! \param[in] client_uid The uid of the crashing client.
    //! \param[in] info Information on the client.
    //! \param[in] broker_sock A socket connected to the PtraceBroker.
    //! \param[out] local_report_id The unique identifier for the report created
    //!     in the local report database. Optional.
    //! \return `true` on success. `false` on failure with a message logged.
    virtual bool HandleExceptionWithBroker(
        pid_t client_process_id,
        uid_t client_uid,
        const ExceptionHandlerProtocol::ClientInformation& info,
        int broker_sock,
        UUID* local_report_id = nullptr) = 0;

    virtual ~Delegate() {}
  };

  ExceptionHandlerServer();
  ~ExceptionHandlerServer();

  //! \brief Sets the handler's PtraceStrategyDecider.
  //!
  //! If this method is not called, a default PtraceStrategyDecider will be
  //! used.
  void SetPtraceStrategyDecider(std::unique_ptr<PtraceStrategyDecider> decider);

  //! \brief Initializes this object.
  //!
  //! This method must be successfully called before Run().
  //!
  //! \param[in] sock A socket on which to receive client requests.
  //! \param[in] multiple_clients `true` if this socket is used by multiple
  //!     clients. Using a broker process is not supported in this
  //!     configuration.
  //! \return `true` on success. `false` on failure with a message logged.
  bool InitializeWithClient(ScopedFileHandle sock, bool multiple_clients);

  //! \brief Runs the exception-handling server.
  //!
  //! This method must only be called once on an ExceptionHandlerServer object.
  //! This method returns when there are no more client connections or Stop()
  //! has been called.
  //!
  //! \param[in] delegate An object to send exceptions to.
  void Run(Delegate* delegate);

  //! \brief Stops a running exception-handling server.
  //!
  //! Stop() may be called at any time, and may be called from a signal handler.
  //! If Stop() is called before Run() it will cause Run() to return as soon as
  //! it is called. It is harmless to call Stop() after Run() has already
  //! returned, or to call Stop() after it has already been called.
  void Stop();

 private:
  struct Event {
    enum class Type {
      // Used by Stop() to shutdown the server.
      kShutdown,

      // A message from a client on a private socket connection.
      kClientMessage,

      // A message from a client on a shared socket connection.
      kSharedSocketMessage
    };

    Type type;
    ScopedFileHandle fd;
  };

  void HandleEvent(Event* event, uint32_t event_type);
  bool InstallClientSocket(ScopedFileHandle socket, Event::Type type);
  bool UninstallClientSocket(Event* event);
  bool ReceiveClientMessage(Event* event);
  bool HandleCrashDumpRequest(
      const ucred& creds,
      const ExceptionHandlerProtocol::ClientInformation& client_info,
      VMAddress requesting_thread_stack_address,
      int client_sock,
      bool multiple_clients);

#if defined(STARBOARD)
  bool HandleAddEvergreenInfoRequest(
      const ucred& creds,
      const ExceptionHandlerProtocol::ClientInformation& client_info);
#endif

  std::unordered_map<int, std::unique_ptr<Event>> clients_;
  std::unique_ptr<Event> shutdown_event_;
  std::unique_ptr<PtraceStrategyDecider> strategy_decider_;
  Delegate* delegate_;
  ScopedFileHandle pollfd_;
  std::atomic<bool> keep_running_;
  InitializationStateDcheck initialized_;

  DISALLOW_COPY_AND_ASSIGN(ExceptionHandlerServer);
};

}  // namespace crashpad

#endif  // CRASHPAD_HANDLER_LINUX_EXCEPTION_HANDLER_SERVER_H_
