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

#include "extensions/renderer/bindings/api_binding_util.h"

#include "base/auto_reset.h"
#include "base/check_op.h"
#include "base/notreached.h"
#include "base/observer_list.h"
#include "base/supports_user_data.h"
#include "build/android_buildflags.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "extensions/renderer/bindings/get_per_context_data.h"
#include "extensions/renderer/bindings/js_runner.h"
#include "gin/converter.h"
#include "gin/per_context_data.h"

namespace extensions {
namespace binding {

namespace {

bool g_response_validation_enabled =
#if DCHECK_IS_ON()
    true;
#else
    false;
#endif

}  // namespace

class ContextInvalidationData : public base::SupportsUserData::Data {
 public:
  ContextInvalidationData();

  ContextInvalidationData(const ContextInvalidationData&) = delete;
  ContextInvalidationData& operator=(const ContextInvalidationData&) = delete;

  ~ContextInvalidationData() override;

  static constexpr char kPerContextDataKey[] = "extension_context_invalidation";

  void Invalidate();

  void AddListener(ContextInvalidationListener* listener);
  void RemoveListener(ContextInvalidationListener* listener);

  bool is_context_valid() const { return is_context_valid_; }

 private:
  bool is_context_valid_ = true;
  base::ObserverList<ContextInvalidationListener>::Unchecked
      invalidation_listeners_;
};

constexpr char ContextInvalidationData::kPerContextDataKey[];

ContextInvalidationData::ContextInvalidationData() = default;
ContextInvalidationData::~ContextInvalidationData() {
  if (is_context_valid_)
    Invalidate();
}

void ContextInvalidationData::AddListener(
    ContextInvalidationListener* listener) {
  DCHECK(is_context_valid_);
  invalidation_listeners_.AddObserver(listener);
}

void ContextInvalidationData::RemoveListener(
    ContextInvalidationListener* listener) {
  DCHECK(invalidation_listeners_.HasObserver(listener));
  invalidation_listeners_.RemoveObserver(listener);
}

void ContextInvalidationData::Invalidate() {
  DCHECK(is_context_valid_);
  is_context_valid_ = false;

  for (ContextInvalidationListener& listener : invalidation_listeners_)
    listener.OnInvalidated();
}

bool IsContextValid(v8::Local<v8::Context> context) {
  gin::PerContextData* per_context_data = gin::PerContextData::From(context);
  if (!per_context_data)
    return false;

  auto* invalidation_data =
      static_cast<ContextInvalidationData*>(per_context_data->GetUserData(
          ContextInvalidationData::kPerContextDataKey));
  // The context is valid if we've never created invalidation data for it, or if
  // we have and it hasn't been marked as invalid.
  bool is_context_valid =
      !invalidation_data || invalidation_data->is_context_valid();

  if (is_context_valid) {
    // As long as the context is valid, there should be an associated
    // JSRunner.
    // TODO(devlin): (Likely) Remove this once https://crbug.com/819968, since
    // this shouldn't necessarily be a hard dependency. At least downgrade it
    // to a DCHECK.
    CHECK(JSRunner::Get(context));
  }
  return is_context_valid;
}

bool IsContextValidOrThrowError(v8::Local<v8::Context> context) {
  if (IsContextValid(context))
    return true;
  v8::Isolate* isolate = v8::Isolate::GetCurrent();
  isolate->ThrowException(v8::Exception::Error(
      gin::StringToV8(isolate, "Extension context invalidated.")));
  return false;
}

void InvalidateContext(v8::Local<v8::Context> context) {
  ContextInvalidationData* data =
      GetPerContextData<ContextInvalidationData>(context, kCreateIfMissing);
  if (!data)
    return;

  data->Invalidate();
}

std::string GetPlatformString() {
#if BUILDFLAG(IS_CHROMEOS)
  return "chromeos";
#elif BUILDFLAG(IS_LINUX)
  return "linux";
#elif BUILDFLAG(IS_MAC)
  return "mac";
#elif BUILDFLAG(IS_WIN)
  return "win";
#elif BUILDFLAG(IS_DESKTOP_ANDROID)
  return "desktop_android";
#else
  NOTREACHED();
#endif
}

ContextInvalidationListener::ContextInvalidationListener(
    v8::Local<v8::Context> context,
    base::OnceClosure on_invalidated)
    : on_invalidated_(std::move(on_invalidated)),
      context_invalidation_data_(
          GetPerContextData<ContextInvalidationData>(context,
                                                     kCreateIfMissing)) {
  // We should never add an invalidation observer to an invalid context.
  DCHECK(context_invalidation_data_);
  DCHECK(context_invalidation_data_->is_context_valid());
  context_invalidation_data_->AddListener(this);
}

ContextInvalidationListener::~ContextInvalidationListener() {
  // We may have already removed ourselves as a listener (in OnInvalidated())
  // if the context was invalidated previously. Check the context first.
  if (context_invalidation_data_) {
    context_invalidation_data_->RemoveListener(this);
  }
}

void ContextInvalidationListener::OnInvalidated() {
  DCHECK(on_invalidated_) << "OnInvalidated() called twice!";
  DCHECK(context_invalidation_data_);

  // The ContextInvalidationData will be cleaned up soon, so we can't store a
  // reference to it. We also remove ourselves as an observer proactively to
  // avoid leaving a dangling pointer in ContextInvalidationData.
  context_invalidation_data_->RemoveListener(this);
  context_invalidation_data_ = nullptr;

  std::move(on_invalidated_).Run();
}

bool IsResponseValidationEnabled() {
  return g_response_validation_enabled;
}

std::unique_ptr<base::AutoReset<bool>> SetResponseValidationEnabledForTesting(
    bool is_enabled) {
  return std::make_unique<base::AutoReset<bool>>(&g_response_validation_enabled,
                                                 is_enabled);
}

}  // namespace binding
}  // namespace extensions
