/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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 _mozilla_dom_ClientInfo_h
#define _mozilla_dom_ClientInfo_h

#include "X11UndefineNone.h"
#include "mozilla/Maybe.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/UniquePtr.h"
#include "nsCOMPtr.h"
#include "nsString.h"

class nsIPrincipal;
struct nsID;

namespace mozilla {

namespace ipc {
class CSPInfo;
class PrincipalInfo;
}  // namespace ipc

namespace dom {

class IPCClientInfo;
enum class FrameType : uint8_t;
enum class ClientType : uint8_t;

// This class provides a simple structure that represents a global living
// in the system.  Its thread safe and can be transferred across process
// boundaries.  A ClientInfo object can represent either a window or a worker.
class ClientInfo final {
  UniquePtr<IPCClientInfo> mData;

 public:
  ClientInfo(const nsID& aId, ClientType aType,
             const mozilla::ipc::PrincipalInfo& aPrincipalInfo,
             const TimeStamp& aCreationTime);

  ClientInfo(const ClientInfo& aRight);

  ClientInfo& operator=(const ClientInfo& aRight);

  ClientInfo(ClientInfo&& aRight) noexcept;

  ClientInfo& operator=(ClientInfo&& aRight) noexcept;

  explicit ClientInfo(const IPCClientInfo& aData);

  ~ClientInfo();

  bool operator==(const ClientInfo& aRight) const;
  bool operator!=(const ClientInfo& aRight) const;

  // Get the unique identifier chosen at the time of the global's creation.
  const nsID& Id() const;

  // This function should only be called on EnsureClientSource().
  // XXX Bug 1579785 will merge this into the constructor (requiring pass a
  // AgentClusterId)
  void SetAgentClusterId(const nsID& aId);
  const Maybe<nsID>& AgentClusterId() const;

  // Determine what kind of global this is; e.g. Window, Worker, SharedWorker,
  // etc.
  ClientType Type() const;

  // Every global must have a principal that cannot change.
  const mozilla::ipc::PrincipalInfo& PrincipalInfo() const;

  // The time at which the global was created.
  const TimeStamp& CreationTime() const;

  // Each global has the concept of a creation URL.  For the most part this
  // does not change.  The one exception is for about:blank replacement
  // iframes.  In this case the URL starts as "about:blank", but is later
  // overriden with the final URL.
  const nsCString& URL() const;

  // Override the creation URL.  This should only be used for about:blank
  // replacement iframes.
  void SetURL(const nsACString& aURL);

  // The frame type is largely a window concept, but we track it as part
  // of the global here because of the way the Clients WebAPI was designed.
  // This is set at the time the global becomes execution ready.  Workers
  // will always return None.
  mozilla::dom::FrameType FrameType() const;

  // Set the frame type for the global.  This should only happen once the
  // global has become execution ready.
  void SetFrameType(mozilla::dom::FrameType aFrameType);

  // Convert to the ipdl generated type.
  const IPCClientInfo& ToIPC() const;

  // Determine if the client is in private browsing mode.
  bool IsPrivateBrowsing() const;

  // Get a main-thread nsIPrincipal for the client.
  Result<nsCOMPtr<nsIPrincipal>, nsresult> GetPrincipal() const;

  const Maybe<mozilla::ipc::CSPInfo>& GetCspInfo() const;
  void SetCspInfo(const mozilla::ipc::CSPInfo& aCSPInfo);

  const Maybe<mozilla::ipc::CSPInfo>& GetPreloadCspInfo() const;
  void SetPreloadCspInfo(const mozilla::ipc::CSPInfo& aPreloadCSPInfo);
};

}  // namespace dom
}  // namespace mozilla

#endif  // _mozilla_dom_ClientInfo_h
