// Copyright 2016 the V8 project 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_INSPECTOR_V8_CONSOLE_MESSAGE_H_
#define V8_INSPECTOR_V8_CONSOLE_MESSAGE_H_

#include <deque>
#include <map>
#include <set>
#include "include/v8.h"
#include "src/inspector/protocol/Console.h"
#include "src/inspector/protocol/Forward.h"
#include "src/inspector/protocol/Runtime.h"

namespace v8_inspector {

class InspectedContext;
class V8InspectorImpl;
class V8InspectorSessionImpl;
class V8StackTraceImpl;

enum class V8MessageOrigin { kConsole, kException, kRevokedException };

enum class ConsoleAPIType {
  kLog,
  kDebug,
  kInfo,
  kError,
  kWarning,
  kDir,
  kDirXML,
  kTable,
  kTrace,
  kStartGroup,
  kStartGroupCollapsed,
  kEndGroup,
  kClear,
  kAssert,
  kTimeEnd,
  kCount
};

class V8ConsoleMessage {
 public:
  ~V8ConsoleMessage();

  static std::unique_ptr<V8ConsoleMessage> createForConsoleAPI(
      v8::Local<v8::Context> v8Context, int contextId, int groupId,
      V8InspectorImpl* inspector, double timestamp, ConsoleAPIType,
      const std::vector<v8::Local<v8::Value>>& arguments,
      const String16& consoleContext, std::unique_ptr<V8StackTraceImpl>);

  static std::unique_ptr<V8ConsoleMessage> createForException(
      double timestamp, const String16& detailedMessage, const String16& url,
      unsigned lineNumber, unsigned columnNumber,
      std::unique_ptr<V8StackTraceImpl>, int scriptId, v8::Isolate*,
      const String16& message, int contextId, v8::Local<v8::Value> exception,
      unsigned exceptionId);

  static std::unique_ptr<V8ConsoleMessage> createForRevokedException(
      double timestamp, const String16& message, unsigned revokedExceptionId);

  V8MessageOrigin origin() const;
  void reportToFrontend(protocol::Console::Frontend*) const;
  void reportToFrontend(protocol::Runtime::Frontend*, V8InspectorSessionImpl*,
                        bool generatePreview) const;
  ConsoleAPIType type() const;
  void contextDestroyed(int contextId);

  int estimatedSize() const {
    return m_v8Size + static_cast<int>(m_message.length() * sizeof(UChar));
  }

 private:
  V8ConsoleMessage(V8MessageOrigin, double timestamp, const String16& message);

  using Arguments = std::vector<std::unique_ptr<v8::Global<v8::Value>>>;
  std::unique_ptr<protocol::Array<protocol::Runtime::RemoteObject>>
  wrapArguments(V8InspectorSessionImpl*, bool generatePreview) const;
  std::unique_ptr<protocol::Runtime::RemoteObject> wrapException(
      V8InspectorSessionImpl*, bool generatePreview) const;
  void setLocation(const String16& url, unsigned lineNumber,
                   unsigned columnNumber, std::unique_ptr<V8StackTraceImpl>,
                   int scriptId);

  V8MessageOrigin m_origin;
  double m_timestamp;
  String16 m_message;
  String16 m_url;
  unsigned m_lineNumber;
  unsigned m_columnNumber;
  std::unique_ptr<V8StackTraceImpl> m_stackTrace;
  int m_scriptId;
  int m_contextId;
  ConsoleAPIType m_type;
  unsigned m_exceptionId;
  unsigned m_revokedExceptionId;
  int m_v8Size = 0;
  Arguments m_arguments;
  String16 m_detailedMessage;
  String16 m_consoleContext;
};

class V8ConsoleMessageStorage {
 public:
  V8ConsoleMessageStorage(V8InspectorImpl*, int contextGroupId);
  ~V8ConsoleMessageStorage();

  int contextGroupId() { return m_contextGroupId; }
  const std::deque<std::unique_ptr<V8ConsoleMessage>>& messages() const {
    return m_messages;
  }

  void addMessage(std::unique_ptr<V8ConsoleMessage>);
  void contextDestroyed(int contextId);
  void clear();

  bool shouldReportDeprecationMessage(int contextId, const String16& method);
  int count(int contextId, const String16& id);
  bool countReset(int contextId, const String16& id);
  void time(int contextId, const String16& id);
  double timeLog(int contextId, const String16& id);
  double timeEnd(int contextId, const String16& id);
  bool hasTimer(int contextId, const String16& id);

 private:
  V8InspectorImpl* m_inspector;
  int m_contextGroupId;
  int m_estimatedSize = 0;
  std::deque<std::unique_ptr<V8ConsoleMessage>> m_messages;

  struct PerContextData {
    std::set<String16> m_reportedDeprecationMessages;
    // Corresponds to https://console.spec.whatwg.org/#count-map
    std::map<String16, int> m_count;
    // Corresponds to https://console.spec.whatwg.org/#timer-table
    std::map<String16, double> m_time;
  };
  std::map<int, PerContextData> m_data;
};

}  // namespace v8_inspector

#endif  // V8_INSPECTOR_V8_CONSOLE_MESSAGE_H_
