// 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_INSPECTED_CONTEXT_H_
#define V8_INSPECTOR_INSPECTED_CONTEXT_H_

#include <unordered_map>
#include <unordered_set>

#include "src/base/macros.h"
#include "src/debug/debug-interface.h"
#include "src/inspector/string-16.h"

#include "include/v8.h"

namespace v8_inspector {

class InjectedScript;
class InjectedScriptHost;
class V8ContextInfo;
class V8InspectorImpl;

enum class V8InternalValueType { kNone, kEntry, kScope, kScopeList };

class InspectedContext {
 public:
  ~InspectedContext();

  static int contextId(v8::Local<v8::Context>);

  v8::Local<v8::Context> context() const;
  int contextId() const { return m_contextId; }
  int contextGroupId() const { return m_contextGroupId; }
  String16 origin() const { return m_origin; }
  String16 humanReadableName() const { return m_humanReadableName; }
  String16 auxData() const { return m_auxData; }

  bool isReported(int sessionId) const;
  void setReported(int sessionId, bool reported);

  v8::Isolate* isolate() const;
  V8InspectorImpl* inspector() const { return m_inspector; }

  InjectedScript* getInjectedScript(int sessionId);
  InjectedScript* createInjectedScript(int sessionId);
  void discardInjectedScript(int sessionId);

  bool addInternalObject(v8::Local<v8::Object> object,
                         V8InternalValueType type);
  V8InternalValueType getInternalType(v8::Local<v8::Object> object);

 private:
  friend class V8InspectorImpl;
  InspectedContext(V8InspectorImpl*, const V8ContextInfo&, int contextId);

  class WeakCallbackData;

  V8InspectorImpl* m_inspector;
  v8::Global<v8::Context> m_context;
  int m_contextId;
  int m_contextGroupId;
  const String16 m_origin;
  const String16 m_humanReadableName;
  const String16 m_auxData;
  std::unordered_set<int> m_reportedSessionIds;
  std::unordered_map<int, std::unique_ptr<InjectedScript>> m_injectedScripts;
  WeakCallbackData* m_weakCallbackData;
  v8::Global<v8::debug::WeakMap> m_internalObjects;

  DISALLOW_COPY_AND_ASSIGN(InspectedContext);
};

}  // namespace v8_inspector

#endif  // V8_INSPECTOR_INSPECTED_CONTEXT_H_
